hdu 4309 Seikimatsu Occult Tonneru.docx
《hdu 4309 Seikimatsu Occult Tonneru.docx》由会员分享,可在线阅读,更多相关《hdu 4309 Seikimatsu Occult Tonneru.docx(11页珍藏版)》请在冰豆网上搜索。
hdu4309SeikimatsuOccultTonneru
SeikimatsuOccultTonneru
TimeLimit:
12000/6000MS(Java/Others)MemoryLimit:
32768/32768K(Java/Others)
TotalSubmission(s):
392AcceptedSubmission(s):
60
ProblemDescription
Duringtheworldwar,toavoidtheupcomingCarpet-bombingfromTheThirdReich,peopleinHeavenEmpirewenttoGreatTunnelsforsheltering.
ThereareNcitiesinHeavenEmpire,wherepeoplelive,with3kindsofdirectededgesconnectedwitheachother.The1stkindofedgesisoneofGreatTunnels(nomorethan20tunnels)whereacertainnumberofpeoplecanhidehere;peoplecanalsogothroughonetunnelfromonecitytoanother.The2ndkindofedgesistheso-calledModernRoad,whichcanonlyletpeoplegothrough.The3rdkindofedgesiscalledAncientBridgeandalltheedgesofthiskindhavedifferentnamesfromothers,eachofwhichisnamedwithoneofthetwelveconstellations(suchasLibra,Leoandsoon);astheywerebuildsolongtimeago,theycanbeeasilydamagedbyoneperson'spass.Well,foreachbridge,youcanspendacertaindealofmoneytofixit.Oncerepaired,the3rdkindofedgescanletpeoplepasswithoutanylimitation,namely,youcanuseonebridgetotransportcountlesspeople.Asfortheformertwokindsofedges,peoplecaninitiallygothroughthemwithoutanylimitation.
Wewanttoshelterthemostpeoplewiththeleastmoney.
NowpleasetellmethelargestnumberofpeoplewhocanhideintheTunnelsandtheleastmoneyweneedtospendtorealizeourobjective.
Input
MultipleCases.
Thefirstline,twointegers:
N(N<=100),m(m<=1000).Theystandsforthenumberofcitiesandedges.
Thenextline,Nintegers,whichrepresentthenumberofpeopleintheNcities.
Thenmlines,fourintergerseach:
u,v,w,p(1<=u,v<=N,0<=w<=50).Adirectededgeutov,withpindicatingthetypeoftheedge:
ifitisaTunnelthenp<0andwmeansthemaximumnumberpeoplewhocanhideinthethetunnel;ifp==0thenitisaModernRoadwithwmeansnothing;otherwiseitisanAncientBridgewithwrepresentingthecostoffixingthebridge.Wepromisetherearenomorethanoneedgefromutov.
Output
IfnobodycanhideintheTunnels,print“PoorHeavenEmpire”,elseprinttwointegers:
maximumnumberandminimumcost.
SampleInput
44
2110
1200
1300
241-1
343-1
44
2110
1200
1331
241-1
343-1
SampleOutput
40
43
Source
2012Multi-UniversityTrainingContest1
网络流
建图方法:
构造一个S,T;
对于每一个城市,建一条S->i的边,容量为城市的人数(w)
GreatTunnels:
建一条u->T的边,容量为w,然后再建一条u->v的边,容量为无穷大
ModernRoad:
建一条u->v的边,容量为无穷大
AncientBridge:
修复,建一条u->v的边容量为无穷大,花费为w;不修复,建一条u->v容量为1的边
由于AncientBridge最多只有12条,故可进行2^12最大流求解;进行2进制转换,0代表不修复,1代表修复
至于怎样2^12次最大流求解,可以用一个for从0到4096。
(将每一个i化成二进制)
将要修复的cost相加
最后求的最大流量,最小花费。
(亲~,求下载,抛积分~~)
#include
#include
usingnamespacestd;
constintMaxx=1105;
constintINF=1<<30;
structnode
{
intv,next;
intflow;
}map[Maxx*Maxx],map1[Maxx*Maxx];
intuse,head[Maxx],head1[Maxx];
intdis[Maxx];
queueq;
ints,t,n,m;
voidadd(intu,intv,intflow)
{
map[use].v=v;
map[use].flow=flow;
map[use].next=head[u];
head[u]=use++;
map[use].v=u;
map[use].flow=0;
map[use].next=head[v];
head[v]=use++;
}
boolbfs()
{
inti,x,v,high=0,low=0;
memset(dis,0,sizeof(dis));
dis[s]=1;
while(!
q.empty())q.pop();
q.push(s);
while(!
q.empty())
{
x=q.front();
q.pop();
for(i=head[x];i!
=-1;i=map[i].next)
{
intv=map[i].v;
if(map[i].flow>0&&dis[v]==0)
{
dis[v]=dis[x]+1;
if(v==t)returntrue;
q.push(v);
}
}
}
returnfalse;
}
intdfs(ints,intflow)
{
if(s==t)returnflow;
inti,v;
inttmp,cost=0;
for(i=head[s];i!
=-1;i=map[i].next)
{
intv=map[i].v;
if(map[i].flow>0&&dis[s]==dis[v]-1)
{
tmp=dfs(v,min(flow-cost,map[i].flow));
if(tmp>0)
{
map[i].flow-=tmp;
map[i^1].flow+=tmp;
cost+=tmp;
if(flow==cost)break;
}
elsedis[v]=-1;
}
}
returncost;
}
intDinic()
{
intans=0;
while(bfs())ans+=dfs(s,INF);
returnans;
}
voidinit()
{
memset(head,-1,sizeof(head));
memset(head1,-1,sizeof(head1));
use=0;
}
boolvi[15];
intlen=0;
structPoint
{
intu,v,w;
}a[15];
voidchange(intmm)
{
inti=0;
while(mm)
{
vi[i]=mm%2;
mm/=2;
i++;
}
}
intmincost,maxflow;
voidresult()
{
intcost=0;
for(inti=0;i{
if(vi[i]==1)
{
add(a[i].u,a[i].v,INF);
cost+=a[i].w;
}else{
add(a[i].u,a[i].v,1);
}
}
intans=Dinic();
if(maxflow{
maxflow=ans;
mincost=cost;
}elseif(maxflow==ans){
if(mincost>cost)mincost=cost;
}
}
intmain()
{
//freopen("1010.in","r",stdin);
//freopen("out.out","w",stdout);
while(scanf("%d%d",&n,&m)!
=EOF)
{
intu,v,w,i,c,j;
init();
s=n+1;t=n+2;
intx=t+1;
for(i=1;i<=n;i++)
{
scanf("%d",&w);
add(s,i,w);
}
len=0;
boolflag=true;
for(i=0;i{
scanf("%d%d%d%d",&u,&v,&w,&c);
if(c>0)
{
a[len].u=u;
a[len].v=v;
a[len].w=w;
len++;
}elseif(c==0){
add(u,v,INF);
}else{
flag=false;
//add(u,x,INF);
add(u,t,w);
add(u,v,INF);
//x++;
}
}
intpath=use;
for(i=0;i