woj 1542 Countries
题目地址:woj1542
题目思路:就是以前做过的cf的D 细菌那一题
关键是先用并查集,然后给结点编号。
用map映射到0-200以内
代码:
#include<iostream> #include<cstdio> #include<vector> #include<map> using namespace std; #define INF 1000000000 int p[100005]; int u[100005],v[100005],w[100005]; int n,m,q; int d[205][205]; void init() { for(int i=0;i<n;i++) p[i]=i; for(int i=0;i<205;i++) for(int j=0;j<205;j++) d[i][j]=(i==j?0:INF); } int find(int x) { return p[x]==x?x:p[x]=find(p[x]); } int min(int a,int b) { return a<b?a:b; } int tot; void floyd() { for(int k=0;k<205;k++) for(int i=0;i<205;i++) for(int j=0;j<205;j++) { if(d[i][k]!=INF&&d[k][j]!=INF) { d[i][j]=min(d[i][j],d[i][k]+d[k][j]); } } } map<int,int> themap; int main() { while(cin>>n) { if(!n) break; cin >>m; themap.clear(); init(); tot=0; int a,b,c; for(int i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); u[i]=a-1; v[i]=b-1; w[i]=c; } // Union for(int i=0;i<m;i++) { if(w[i]==0) { int x=find(u[i]); int y=find(v[i]); if(x!=y) { p[x]=y; } } } for(int i=0;i<n;i++) if(themap.find(find(i))==themap.end()) { themap[find(i)]=tot++; } for(int i=0;i<m;i++) { int x=themap[find(u[i])]; int y=themap[find(v[i])]; if(x!=y) { d[x][y]=min(d[x][y],w[i]); d[y][x]=min(d[y][x],w[i]); } } floyd(); cin>>q; int s,t; for(int i=0;i<q;i++) { cin>>s>>t; int x=themap[find(s-1)]; int y=themap[find(t-1)]; if(d[x][y]==INF) cout<<-1<<endl; else cout<<d[x][y]<<endl; } } }
posted on 2014-03-31 01:44 814jingqi的ACM 阅读(322) 评论(0) 编辑 收藏 举报