例题11-2
本题目直接套用Kruskal算法中,使用并查集来判断来判断联通量,另外要注意的是本题目中顶点的编号是从1开始的,所以初始化p的时候要小心。
#include<bits/stdc++.h>
using namespace std;
const int maxm=5000;
const int INF=0x3f3f3f3f;
int u[maxm],v[maxm],w[maxm],r[maxm],p[maxm];
int m,n;
int cmp(const int i,const int j){return w[i]<w[j];}//间接排序函数
int find(int x){ return p[x]==x? x : p[x] = find(p[x]);}
int solve()//套用Kruskal的解题方式
{
int ans = INF;
for(int i=0;i<m;i++) r[i]=i;//初始化边序号
sort(r,r+m,cmp);//给边排序
for(int L=0;L<m;L++)
{
int cnt=n;
for(int i=1;i<=n;i++) p[i]=i;//初始化并查集
for(int R=L;R<m;R++)
{
int e = r[R]; int x = find(u[e]); int y = find(v[e]);
if(x != y)
{
p[x]=y;
if(--cnt==1)
{
ans = min(ans,w[r[R]]-w[r[L]]);
break;
}
}
}
}
if(ans == INF) ans = -1;
return ans;//返回最小生成树的权值。
}
int main()
{
//freopen("datain.txt","r",stdin);
//freopen("dataout.txt","w",stdout);
while(cin>>n>>m&&n)
{
for(int i=0;i<m;i++)
cin>>u[i]>>v[i]>>w[i];
cout<<solve()<<endl;
}
return 0;
}
例题11-4(WA)
本题目直接采用floyd算法求传递闭包就可,只是本题目的输出顺序可能有所要求,导致WA。具体原因还没找到。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 25+2;
int m,n,d[maxn][maxn];
map<string,int> n2id;
map<int,string> id2n;
void solve()
{
for(int k=0;k<n;k++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
d[i][j]=d[i][j]||d[i][k]&&d[k][j];
}
int main()
{
//freopen("datain.txt","r",stdin);
//freopen("dataout.txt","w",stdout);
int rnd=1;
while(cin>>n>>m&&n)
{
cout<<"Calling circles for data set "<<rnd++<<":"<<endl;
n2id.clear();
id2n.clear();
int id=0,vis[maxn];
memset(d,0,sizeof(d));
for(int i=0;i<n;i++) d[i][i]=1;
memset(vis,0,sizeof(vis));
for(int i=0;i<m;i++)
{
string s1,s2;
cin>>s1>>s2;
if(!n2id.count(s1))
{
n2id[s1]=id;
id2n[id]=s1;
id++;
}
if(!n2id.count(s2))
{
n2id[s2]=id;
id2n[id]=s2;
id++;
}
d[n2id[s1]][n2id[s2]]=1;
}
solve();
if(m){
for (int i=0;i<n;i++)
{
if(!vis[i])
{
cout<<id2n[i];
vis[i]=1;
for(int j=0;j<n;j++)
{
if(d[i][j]&&d[i][j]==d[j][i]&&!vis[j])
{
cout<<", "<<id2n[j];
vis[j]=1;
}
}
cout<<endl;
}
}
cout<<endl;
}
}
return 0;
}
例题11-5
本题采用的算法思想也是floyd算法,具体代码如下:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100+10;
int m,n,d[maxn][maxn];
void solve()
{
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(d[i][k]!=-1&&d[k][j]!=-1)
{
if(d[i][j]==-1)
{
d[i][j]=max(d[i][k],d[k][j]);
}
else
d[i][j]=min(d[i][j],max(d[i][k],d[k][j]));
}
}
int main()
{
//freopen("datain.txt","r",stdin);
//freopen("dataout.txt","w",stdout);
int Q,rnd=1;
while(cin>>n>>m>>Q&&n)
{
if(rnd>1) cout<<endl;
cout<<"Case #"<<rnd++<<endl;
memset(d,-1,sizeof(d));
for(int i=0;i<m;i++)
{
int u,v,w;
cin>>u>>v>>w;
d[u][v]=w;
d[v][u]=w;
}
solve();
for(int i=0;i<Q;i++)
{
int u1,v1;
cin>>u1>>v1;
if(d[u1][v1]!=-1)
cout<<d[u1][v1]<<endl;
else
cout<<"no path"<<endl;
}
}
return 0;
}