题目地址: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;
}
}
}