首页 > 代码库 > Being a Hero
Being a Hero
zoj3241:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3241
题意:一个国家的地图是一张n个点m条边的有向图。你保卫了国家成为了英雄,现在国王答应给你一些城市。国王居住在首都,编号为1,但他不想随意的到达你的领地,所以你必须破坏一些路,使得从首都到你所拥有的所有城市不连通。而破坏这些路需要花钱。国王给了你f个城市供你选择,每个城市有一个价值。你最后的总收益=你选择的城市的价值之和-破坏路花费的钱。现在让你输出最大的收益,以及完成这样的收益应该破坏哪些路。
首先对于表示这个国家地图的有向边(u,v,cost),直接在图中建一条一样的边(u,v,cost)。对于供你选择的城市i,假设它的价值是value,创建一个汇点T,建一条(i,T,value)的边。然后以1为源点,T为汇点,求最小割即可。
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdio> 5 #include<queue> 6 using namespace std; 7 const int N=1205; 8 const int INF=(1<<29); 9 const int M=300000; 10 struct Node{ 11 int v; 12 int f; 13 int next; 14 }edge[M]; 15 int n,m,u,v,w,cnt,sx,ex,top,f; 16 int head[N],pre[N]; 17 int xx[M],yy[M],ans[M]; 18 bool vis[N]; 19 void init(){ 20 cnt=0; 21 memset(head,-1,sizeof(head)); 22 } 23 void add(int u,int v,int w){ 24 edge[cnt].v=v; 25 edge[cnt].f=w; 26 edge[cnt].next=head[u]; 27 head[u]=cnt++; 28 edge[cnt].f=0; 29 edge[cnt].v=u; 30 edge[cnt].next=head[v]; 31 head[v]=cnt++; 32 } 33 bool BFS(){ 34 memset(pre,0,sizeof(pre)); 35 pre[sx]=1; 36 queue<int>Q; 37 Q.push(sx); 38 while(!Q.empty()){ 39 int d=Q.front(); 40 Q.pop(); 41 for(int i=head[d];i!=-1;i=edge[i].next ){ 42 if(edge[i].f&&!pre[edge[i].v]){ 43 pre[edge[i].v]=pre[d]+1; 44 Q.push(edge[i].v); 45 } 46 } 47 } 48 return pre[ex]>0; 49 } 50 int dinic(int flow,int ps){ 51 int f=flow; 52 if(ps==ex)return f; 53 for(int i=head[ps];i!=-1;i=edge[i].next){ 54 if(edge[i].f&&pre[edge[i].v]==pre[ps]+1){ 55 int a=edge[i].f; 56 int t=dinic(min(a,flow),edge[i].v); 57 edge[i].f-=t; 58 edge[i^1].f+=t; 59 flow-=t; 60 if(flow<=0)break; 61 } 62 63 } 64 if(f-flow<=0)pre[ps]=-1; 65 return f-flow; 66 } 67 int solve(){ 68 int sum=0; 69 while(BFS()) 70 sum+=dinic(INF,sx); 71 return sum; 72 } 73 void DFS(int u){ 74 for(int i=head[u];i!=-1;i=edge[i].next){ 75 int v=edge[i].v; 76 if(!vis[v]&&edge[i].f>0){ 77 vis[v]=1; 78 DFS(v); 79 } 80 } 81 } 82 int main() { 83 int T,sum,tt=1; 84 scanf("%d",&T); 85 while(T--) { 86 scanf("%d%d%d",&n,&m,&f); 87 sum=0; 88 init(); 89 for(int i=1;i<=m;i++){ 90 scanf("%d%d%d",&u,&v,&w); 91 xx[i]=u,yy[i]=v; 92 add(u,v,w); 93 } 94 for(int i=1;i<=f;i++){ 95 scanf("%d%d",&u,&w); 96 add(u,n+1,w); 97 sum+=w; 98 } 99 sx=1,ex=n+1;top=0;100 int as=sum-solve();101 memset(vis,0,sizeof(vis));102 vis[1]=1;103 printf("Case %d: %d\n",tt++,as);104 DFS(1);105 for(int i=1;i<=m;i++){106 if(vis[xx[i]]&&!vis[yy[i]]){107 ans[++top]=i;108 }109 }110 printf("%d",top);111 for(int i=1;i<=top;i++)112 printf(" %d",ans[i]);113 puts("");114 }115 return 0;116 }
Being a Hero
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。