您的位置:首页 > 其它

hdu 1863 Kruskal起步

2017-03-23 23:44 253 查看
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。

Input

测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N

行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。

Output

对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。

Sample Input

3 3

1 2 1

1 3 2

2 3 4

1 3

2 3 2

0 100

Sample Output

3
?

Kruskal() 用并查集维护联通的点,如果联通证明已经是处理过的点了,只需找没处理的点,这样每次找的路径一定是最小的。

#include <bits/stdc++.h>
//#include <ext/pb_ds/tree_policy.hpp>
//#include <ext/pb_ds/assoc_container.hpp>
//using namespace __gnu_pbds;
using namespace std;

#define pi acos(-1)
#define endl '\n'
#define me(x) memset(x,0,sizeof(x));
#define foreach(it,a) for(__typeof((a).begin()) it=(a).begin();it!=(a).end();it++)
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL LINF=0x3f3f3f3f3f3f3f3fLL;
const int dx[]={-1,0,1,0,-1,-1,1,1};
const int dy[]={0,1,0,-1,1,-1,1,-1};
const int maxn=1e3+5;
const int maxx=1e5+100;
const double EPS=1e-7;
const int mod=1000000007;
template<class T>inline T min(T a,T b,T c) { return min(min(a,b),c);}
template<class T>inline T max(T a,T b,T c) { return max(max(a,b),c);}
template<class T>inline T min(T a,T b,T c,T d) { return min(min(a,b),min(c,d));}
template<class T>inline T max(T a,T b,T c,T d) { return max(max(a,b),max(c,d));}
//typedef tree<pt,null_type,less< pt >,rb_tree_tag,tree_order_statistics_node_update> rbtree;
/*lch[root] = build(L1,p-1,L2+1,L2+cnt);
rch[root] = build(p+1,R1,L2+cnt+1,R2);中前*/
/*lch[root] = build(L1,p-1,L2,L2+cnt-1);
rch[root] = build(p+1,R1,L2+cnt,R2-1);中后*/
long long gcd(long long a , long long b){if(b==0) return a;a%=b;return gcd(b,a);}

int n,m,fa[maxx];
struct node
{
int x,y;
LL cost;//cost存路程
}Q[maxx];
int fi(int x)
{
return fa[x]==x?x:fa[x]=fi(fa[x]);
}
bool cmp(node a,node b)
{
return a.cost<b.cost;//找路程小的
}
void unio(int x,int y)
{
int p1=fi(x),p2=fi(y);
if(p1!=p2) fa[p1]=p2;
}
LL Kruskal()
{
LL ans=0;
sort(Q+1,Q+1+n,cmp);
for(int i=1;i<=n;i++)
{
if(fi(Q[i].x)==fi(Q[i].y))//是否联通,如果已经联通就继续
continue;
unio(Q[i].x,Q[i].y);
ans+=Q[i].cost;
}
return ans;
}

int main()
{
while(cin>>n>>m)
{
if(n==0) break;
for(int i=1;i<=m;i++)
fa[i]=i;
for(int i=1;i<=n;i++)
cin>>Q[i].x>>Q[i].y>>Q[i].cost;
LL ans=Kruskal();
for(int i=1;i<=m;i++)
{
if(fi(1)!=fi(i))
ans=-1;
}
if(ans==-1)
cout<<"?"<<endl;
else cout<<ans<<endl;
}
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: