★★ 輸入文件:roads.in 輸出文件:roads.out 簡單對比 時間限制:1 s 記憶體限制:128 MB 譯 by CmYkRgB123 描述 Farmer John 剛剛得到了幾個新農場!他想把這幾個農場用路連接起來,這樣他就可以通過筆直的公路從一個農場到另一個農場了。現在已經有了幾條連 ...
★★ 輸入文件:roads.in
輸出文件:roads.out
簡單對比
時間限制:1 s
記憶體限制:128 MB
譯 by CmYkRgB123
描述
Farmer John 剛剛得到了幾個新農場!他想把這幾個農場用路連接起來,這樣他就可以通過筆直的公路從一個農場到另一個農場了。現在已經有了幾條連接著的農場。
N (1 ≤ N ≤ 1,000) 個農場中,每個農場的位置在坐標平面的 (Xi, Yi) (0 ≤ Xi ≤ 1,000,000; 0 ≤
Yi ≤ 1,000,000)。已經有 M (1 ≤ M ≤ 1,000) 條路以前就被建好了。請你幫助 Farmer John
考慮建設儘量少長度的額外的路,使他的農場連在一起。
輸入
* 第 1 行: 兩個整數: N , M
* 第 2..N+1 行: 兩個整數 Xi , Yi
* 第 N+2..N+M+2 行: 兩個整數: i , j, 表示已經存在從農場i到農場j的路。
輸出
* 第 1 行: 額外的路的最少長度,保留2小數。 請使用 64 位的浮點數。
樣例輸入
4 1
1 1
3 1
2 3
4 3
1 4
樣例輸出
4.00
好久沒寫最小生成樹了結果爆了一堆bug。。
對於已經建造的道路,我們可以把它的權值設置成0
然後跑裸地kruskal
註意記憶體限制!!!!!!!!!!!
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #define INF 0x7ffff 7 using namespace std; 8 const int MAXN=1001; 9 int vis[MAXN][MAXN];// 記錄兩個城市之間是否已經有道路相連 10 double dis[MAXN][MAXN]; 11 struct node 12 { 13 int u,v,nxt; 14 double w; 15 }edge[1000001]; 16 int f[MAXN*3]; 17 int num=1; 18 struct pos 19 { 20 long long int x,y; 21 }where[MAXN*3]; 22 int n,m; 23 double ans=0; 24 int read(int & n) 25 { 26 int flag=0,x=0;char c='/'; 27 while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;} 28 while(c>='0'&&c<='9')x=x*10+(c-48),c=getchar(); 29 if(flag)n=-x; 30 else n=x; 31 } 32 void deal_dis() 33 { 34 //for(int i=1;i<=n;i++) 35 // for(int j=1;j<i;j++) 36 // dis[i][j]=INF; 37 38 for(int i=1;i<=n;i++) 39 for(int j=1;j<i;j++) 40 dis[i][j]=sqrt((where[i].x-where[j].x)*(where[i].x-where[j].x)+(where[i].y-where[j].y)*(where[i].y-where[j].y)); 41 42 /*for(int i=1;i<=n;i++) 43 { 44 for(int j=1;j<i;j++) 45 printf("%.2lf ",dis[i][j]); 46 printf("\n"); 47 }*/ 48 //cout<<dis[219][65]; 49 } 50 void add_edge(int p,int q,double we) 51 { 52 edge[num].u=p; 53 edge[num].v=q; 54 edge[num].w=we; 55 // cout<<edge[num].w<<endl; 56 num++; 57 } 58 int find(int x) 59 { 60 if(f[x]!=x) 61 f[x]=find(f[x]); 62 return f[x]; 63 } 64 int unionn(int x,int y) 65 { 66 int fx=find(x); 67 int fy=find(y); 68 f[fx]=fy; 69 } 70 int comp(const node & a,const node & b) 71 { 72 return a.w<b.w; 73 } 74 void kruskal() 75 { 76 sort(edge+1,edge+num+1,comp); 77 int k=1; 78 for(int i=1;i<=num;i++) 79 { 80 if(find(edge[i].u)!=find(edge[i].v)) 81 { 82 unionn(edge[i].u,edge[i].v); 83 k++; 84 ans=ans+edge[i].w; 85 } 86 if(k==n) 87 break; 88 } 89 printf("%.2lf",ans); 90 } 91 int main() 92 { 93 freopen("roads.in","r",stdin); 94 freopen("roads.out","w",stdout); 95 read(n);read(m); 96 for(int i=1;i<=n;i++) 97 cin>>where[i].x>>where[i].y,f[i]=i; 98 99 for(int i=1;i<=m;i++) 100 { 101 int x,y; 102 read(x);read(y); 103 add_edge(x,y,0.00); 104 vis[x][y]=1; 105 } 106 107 deal_dis(); 108 109 for(int i=1;i<=n;i++) 110 for(int j=1;j<i;j++) 111 if(i!=j&&vis[i][j]==0) 112 add_edge(i,j,dis[i][j]); 113 114 kruskal(); 115 return 0; 116 }