您的位置:首页 > 产品设计 > UI/UE

zoj 2587 Unique Attack(最小割的唯一性判定)

2014-04-29 14:10 281 查看
UniqueAttack

TimeLimit:5Seconds
MemoryLimit:32768KB

NsupercomputersintheUnitedStatesofAntarcticaareconnectedintoanetwork.Anetworkhasasimpletopology:Mdifferentpairsofsupercomputersareconnectedtoeachotherbyanopticalfibre.Allconnectionsaretwo-way,thatis,theycanbeused
inbothdirections.Datacanbetransmittedfromonecomputertoanothereitherdirectlybyafibre,orusingsomeintermediatecomputers.

Agroupofterroristsisplanningtoattackthenetwork.Theirgoalistoseparatetwomaincomputersofthenetwork,sothatthereisnowaytotransmitdatafromoneofthemtoanother.Foreachfibretheterroristshavecalculatedthesumofmoneythey
needtodestroythefibre.Ofcourse,theywanttominimizethecostoftheoperation,soitisrequiredthatthetotalsumspentfordestroyingthefibreswasminimalpossible.

Nowtheleadersofthegroupwonderwhetherthereisonlyonewaytodotheselectedoperation.Thatis,theywanttoknowiftherearenotwodifferentsetsoffibreconnectionsthatcanbedestroyed,suchthatthemainsupercomputerscannotconnectto
eachotherafteritandthecostoftheoperationisminimalpossible.

Input

Theinputfileconsistsofseveralcases.Ineachcase,thefirstlineoftheinputfilecontainsN,M,AandB(2<=N<=800,1<=M<=10000,1<=A,B<=N,A!=B),specifyingthenumberofsupercomputersinthenetwork,thenumberoffibreconnections,
andthenumbersofthemainsupercomputersrespectively.Acasewith4zerosindicatestheendoffile.

NextMlinesdescribefibreconnections.Foreachconnectionthenumbersofthecomputersitconnectsaregivenandthecostofdestroyingthisconnection.Itisguaranteedthatallcostsarenon-negativeintegernumbersnotexceeding105,notwocomputers
aredirectlyconnectedbymorethanonefibre,nofibreconnectsacomputertoitselfandinitiallythereisthewaytotransmitdatafromonemainsupercomputertoanother.

Output

Ifthereisonlyonewaytoperformtheoperation,output"UNIQUE"inasingleline.Intheothercaseoutput"AMBIGUOUS".

SampleInput

4412
121
242
132
341
4412
121
241
132
341
0000


SampleOutput

UNIQUE
AMBIGUOUS


题意:给出一个无向图,每条边都有一个花费,给出s和t,要破坏一些边,使得s和t不连通,并且破坏的边的总花费要最小。问是否存在多种破坏边的方案。

思路:转化为求原图的最小割是否唯一。求完最大流后,以未满流的边分别建正图和反图,分别以s点和t点开始dfs,dfs结束后,若有点没有访问过,那么这个点不属于S和T集合,那么这些点构成的边只要任意割一条就好了,所以若有点没有访问过,则最小割不唯一。


AC代码:

#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<queue>
#include<ctime>
#include<vector>
#include<algorithm>
#definelllonglong
#defineL(rt)(rt<<1)
#defineR(rt)(rt<<1|1)
usingnamespacestd;

constintINF=1e9;
constintmaxn=1005;

structEdge{
intu,v,cap,flow,next;
}et[maxn*maxn];
intlow[maxn],cnt[maxn],dis[maxn],pre[maxn],cur[maxn],eh[maxn],col[maxn];
intn,m,s,t,num;
vector<int>G[maxn],RG[maxn];
voidinit(){
memset(eh,-1,sizeof(eh));
memset(col,0,sizeof(col));
for(inti=0;i<=n;i++)
{
G[i].clear();
RG[i].clear();
}
num=0;
}
voidadd(intu,intv,intcap,intflow){
Edgee={u,v,cap,flow,eh[u]};
et[num]=e;
eh[u]=num++;
}
voidaddedge(intu,intv,intcap){
add(u,v,cap,0);
add(v,u,0,0);
}
intisap(ints,intt,intnv){
intu,v,now,flow=0;
memset(low,0,sizeof(low));
memset(cnt,0,sizeof(cnt));
memset(dis,0,sizeof(dis));
for(u=0;u<=nv;u++)cur[u]=eh[u];
low[s]=INF,cnt[0]=nv,u=s;
while(dis[s]<nv)
{
for(now=cur[u];now!=-1;now=et[now].next)
if(et[now].cap-et[now].flow&&dis[u]==dis[v=et[now].v]+1)break;
if(now!=-1)
{
cur[u]=pre[v]=now;
low[v]=min(low[u],et[now].cap-et[now].flow);
u=v;
if(u==t)
{
for(;u!=s;u=et[pre[u]].u)
{
et[pre[u]].flow+=low[t];
et[pre[u]^1].flow-=low[t];
}
flow+=low[t];
low[s]=INF;
}
}
else
{
if(--cnt[dis[u]]==0)break;
dis[u]=nv,cur[u]=eh[u];
for(now=eh[u];now!=-1;now=et[now].next)
if(et[now].cap-et[now].flow&&dis[u]>dis[et[now].v]+1)
dis[u]=dis[et[now].v]+1;
cnt[dis[u]]++;
if(u!=s)u=et[pre[u]].u;
}
}
returnflow;
}
voiddfs1(intu){
col[u]=1;
for(inti=0;i<(int)G[u].size();i++)
{
intv=G[u][i];
if(!col[v])dfs1(v);
}
}
voiddfs2(intu){
col[u]=2;
for(inti=0;i<(int)RG[u].size();i++)
{
intv=RG[u][i];
if(!col[v])dfs2(v);
}
}
booljudge(){
dfs1(s);
dfs2(t);
for(inti=1;i<=n;i++)
if(!col[i])returnfalse;
returntrue;
}
intmain()
{
inta,b,c;
while(scanf("%d%d%d%d",&n,&m,&s,&t),n||m||s||t)
{
init();
while(m--)
{
scanf("%d%d%d",&a,&b,&c);
addedge(a,b,c);
addedge(b,a,c);
}
isap(s,t,n+1);
for(inti=0;i<num;i+=2)
if(et[i].cap-et[i].flow)
{
intu=et[i].u,v=et[i].v;
G[u].push_back(v);
RG[v].push_back(u);
}
if(judge())printf("UNIQUE\n");
elseprintf("AMBIGUOUS\n");
}
return0;
}

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