您的位置:首页 > 其它

2017江苏省省赛 Roads(全局最小割)

2017-09-07 10:17 246 查看

Roads

时间限制:2Sec内存限制:256MB
提交:6解决:2
[提交][状态][讨论版]

题目描述

InICPCCamp,therearentownsconvenientlylabeledwith1,2,…,nandmbidirectionalroadsplannedtobebuilt.Thei-throadwillbebuiltbetweencitiesaiandbiwithcostci.ThebuildersinICPCCampwillbuildthe(n−1)roadswiththeleasttotalcosttoconnectanyoftwocitiesdirectlyorindirectly.

Bobo,themayorofICPCCampisgoingtoremovesomeoftheroadsfromtheconstructionplan.Hewouldliketoknowtheminimumnumberroadstoberemovedtostrictlyincreasesthetotalcost.

Notethatthetotalcostisconsideredas+∞ifnovalid(n−1)roadsexistafterremoving.Itisalsocountedas"totalcoststrictlyincreases".

输入

Theinputcontainszeroormoretestcasesandisterminatedbyend-of-file.Foreachtestcase:
Thefirstlinecontainstwointegersnandm.Thei-thofthefollowingmlinescontainsai,bi,ci.
2≤n≤50,n−1≤m≤n2,1≤ai,bi≤n,1≤ci≤109
Anytwocitieswillbeconnectedifallmroadsarebuilt.
Thesumofndoesnotexceed103.

输出

Foreachcase,outputanintegerwhichdenotestheresult.

样例输入

33
121
132
233
34
121
121
132
133
34
121
121
132
132
46
121
131
141
231
241
341

样例输出

1
1
2
3


#include<bits/stdc++.h>
#defineinf0x3f3f3f3f
#definemet(a,b)memset(a,b,sizeofa)
#definepbpush_back
#definempmake_pair
#definerep(i,l,r)for(inti=(l);i<=(r);++i)
#defineinf0x3f3f3f3f
usingnamespacestd;
typedeflonglongll;
constintN=1e2+50;;
constintM=17;
constintmod=19260817;
constintmo=123;
constdoublepi=acos(-1.0);
typedefpair<int,int>pii;
llqpow(intx,intqq){llf=1,p=x;while(qq){if(qq&1)f=f*p%mod;p=1LL*p*p%mod;qq>>=1;}}
intn,m;
intfa
,wage
,edg

;
boolvis
,in_set
;
structman{
intu,v,w;
booloperator<(constman&s)const{
returnw<s.w;
}
}a[N*N];
intfindFa(intx){
returnfa[x]==x?x:fa[x]=findFa(fa[x]);
}
voidunionFa(intx,inty){
if(findFa(x)==findFa(y))return;
fa[findFa(x)]=findFa(y);
}
intsearch(int&s,int&t){
met(vis,false);
met(wage,0);
intu,mincut,mx;
for(inti=1;i<=n;i++){
u=mx=-1;
for(intj=1;j<=n;j++){
if(!in_set[j]&&!vis[j]&&wage[j]>mx)mx=wage[u=j];
}
if(u==-1)returnmincut;
vis[u]=true;
s=t,t=u;
mincut=mx;
for(intj=1;j<=n;j++){
if(!in_set[j]&&!vis[j])wage[j]+=edg[u][j];
}
}
returnmincut;
}
intstoer_wagner(){
intmincut=inf,s,t,ret;
for(inti=1;i<n;i++){
ret=search(s,t);
in_set[t]=true;
if(ret!=0&&ret<mincut)mincut=ret;//加ret!=0是为了求所有联通块的最小割
for(intj=1;j<=n;j++)if(!in_set[j])edg[s][j]=(edg[j][s]+=edg[j][t]);
}
returnmincut;
}
intmain(){
while(~scanf("%d%d",&n,&m)){
for(inti=0;i<=n;i++)fa[i]=i;
for(inti=0;i<m;i++){
scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
}
sort(a,a+m);
intans=inf,cnt=0;
for(inti=0;i<m;){
intnow=i,w=a[i].w;
met(edg,0);met(in_set,false);
for(;a[i].w==w&&i<m;i++){
if(findFa(a[i].u)!=findFa(a[i].v)){
edg[findFa(a[i].u)][findFa(a[i].v)]++;
edg[findFa(a[i].v)][findFa(a[i].u)]++;
}
}
ans=min(ans,stoer_wagner());
for(inti=now;a[i].w==w&&i<m;i++){
if(findFa(a[i].u)!=findFa(a[i].v)){
unionFa(a[i].u,a[i].v);
cnt++;
}
}
if(cnt>=n-1)break;
}
printf("%d\n",ans);
}
return0;
}



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