POJ3184 Ikki's Story I - Road Reconstruction(最大流)

求一次最大流后,分别对所有满流的边的容量+1,然后看是否存在增广路。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #include<algorithm>
  5 using namespace std;
  6 #define INF (1<<30)
  7 #define MAXN 555
  8 #define MAXM 11111
  9
 10 struct Edge{
 11     int v,cap,flow,next;
 12 }edge[MAXM];
 13 int vs,vt,NE,NV;
 14 int head[MAXN];
 15
 16 void addEdge(int u,int v,int cap){
 17     edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=0;
 18     edge[NE].next=head[u]; head[u]=NE++;
 19     edge[NE].v=u; edge[NE].cap=0; edge[NE].flow=0;
 20     edge[NE].next=head[v]; head[v]=NE++;
 21 }
 22
 23 int level[MAXN];
 24 int gap[MAXN];
 25 void bfs(){
 26     memset(level,-1,sizeof(level));
 27     memset(gap,0,sizeof(gap));
 28     level[vt]=0;
 29     gap[level[vt]]++;
 30     queue<int> que;
 31     que.push(vt);
 32     while(!que.empty()){
 33         int u=que.front(); que.pop();
 34         for(int i=head[u]; i!=-1; i=edge[i].next){
 35             int v=edge[i].v;
 36             if(level[v]!=-1) continue;
 37             level[v]=level[u]+1;
 38             gap[level[v]]++;
 39             que.push(v);
 40         }
 41     }
 42 }
 43
 44 int pre[MAXN];
 45 int cur[MAXN];
 46 int ISAP(bool statue){
 47     bfs();
 48     memset(pre,-1,sizeof(pre));
 49     memcpy(cur,head,sizeof(head));
 50     int u=pre[vs]=vs,flow=0,aug=INF;
 51     gap[0]=NV;
 52     while(level[vs]<NV){
 53         bool flag=false;
 54         for(int &i=cur[u]; i!=-1; i=edge[i].next){
 55             int v=edge[i].v;
 56             if(edge[i].cap!=edge[i].flow && level[u]==level[v]+1){
 57                 flag=true;
 58                 pre[v]=u;
 59                 u=v;
 60                 //aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap));
 61                 aug=min(aug,edge[i].cap-edge[i].flow);
 62                 if(v==vt){
 63                     if(statue&&aug) return 1;
 64                     flow+=aug;
 65                     for(u=pre[v]; v!=vs; v=u,u=pre[u]){
 66                         edge[cur[u]].flow+=aug;
 67                         edge[cur[u]^1].flow-=aug;
 68                     }
 69                     //aug=-1;
 70                     aug=INF;
 71                 }
 72                 break;
 73             }
 74         }
 75         if(flag) continue;
 76         int minlevel=NV;
 77         for(int i=head[u]; i!=-1; i=edge[i].next){
 78             int v=edge[i].v;
 79             if(edge[i].cap!=edge[i].flow && level[v]<minlevel){
 80                 minlevel=level[v];
 81                 cur[u]=i;
 82             }
 83         }
 84         if(--gap[level[u]]==0) break;
 85         level[u]=minlevel+1;
 86         gap[level[u]]++;
 87         u=pre[u];
 88     }
 89     return flow;
 90 }
 91 int main(){
 92     int n,m,a,b,c;
 93     scanf("%d%d",&n,&m);
 94     vs=0; vt=n-1; NV=n; NE=0;
 95     memset(head,-1,sizeof(head));
 96     while(m--){
 97         scanf("%d%d%d",&a,&b,&c);
 98         addEdge(a,b,c);
 99     }
100     ISAP(0);
101     int cnt=0;
102     for(int i=0; i<NE; i+=2){
103         if(edge[i].flow!=edge[i].cap) continue;
104         ++edge[i].cap;
105         if(ISAP(1)) ++cnt;
106         --edge[i].cap;
107     }
108     printf("%d",cnt);
109     return 0;
110 }

POJ3184 Ikki's Story I - Road Reconstruction(最大流)

时间: 2024-10-01 14:37:49

POJ3184 Ikki's Story I - Road Reconstruction(最大流)的相关文章

POJ 3204 Ikki&#39;s Story I - Road Reconstruction 最大流关键边

题目大意:给出一个裸的最大流的图,求这个图中哪一条边的流量增大会使整个图的最大流增大. 前言:POJ400题达成~~~ 思路:真心不知道这个题用预流推进怎么做,先给写预流推进的犇们点根蜡.. 我用的是Dinic,写起来就比较轻松.模拟一下Dinic的过程,加入一条边的流量增大就会使S到T的最大流增大的充要条件是 1.S->当前边的起始节点可以在残余网络中联通 2.当前边的终止节点->T可以在参与网络中联通 这样的话,增加了这条边的流量,就会有至少一的流量从S流到T,也就是增加了整个图的最大流.

poj 3204 Ikki&#39;s Story I - Road Reconstruction

Ikki's Story I - Road Reconstruction 题意:有N个顶点和M条边N, M (N ≤ 500, M ≤ 5,000)  ,试图改变图中的一条边使得从0到N-1的流量增加:问这样的边有几条? 思路:刚最大流入门,之后一看就觉得满流的边就是答案..真是太天真了.之后看了题解,发现满流只是前提(即使满流是几次残量的叠加也是一样),还有一个条件是,该路径的最大流量只受该边影响:即可以从S和T遍历到该边的两个端点,这就是为什么之后还要dfs给点涂色的原因:涂色前要对残余网络

POJ 3204 Ikki&#39;s Story I - Road Reconstruction(最大流)

POJ 3204 Ikki's Story I - Road Reconstruction 题目链接 题意:给定一个有向图,求出最大流后,问哪些边增加容量后,可以使最大流增加 思路:对于一个可以增加的,必然原来就是满流,并且从源点到汇点,的一条路径上,都是还有残留容量的,这样只要从源点和汇点分别出发dfs一遍,标记掉经过点,然后枚举满流边,如果两端都是标记过的点,这个边就是可以增加的 代码: #include <cstdio> #include <cstring> #include

【POJ 3204】Ikki&#39;s Story I - Road Reconstruction

Ikki's Story I - Road Reconstruction Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 7089   Accepted: 2039 Description Ikki is the king of a small country – Phoenix, Phoenix is so small that there is only one city that is responsible fo

图论常用算法之一 POJ图论题集【转载】

POJ图论分类[转] 一个很不错的图论分类,非常感谢原版的作者!!!在这里分享给大家,爱好图论的ACMer不寂寞了... (很抱歉没有找到此题集整理的原创作者,感谢知情的朋友给个原创链接) POJ:http://poj.org/ 1062* 昂贵的聘礼 枚举等级限制+dijkstra 1087* A Plug for UNIX 2分匹配 1094 Sorting It All Out floyd 或 拓扑 1112* Team Them Up! 2分图染色+DP 1125 Stockbroker

网络流(进阶)

最大流:DINIC or SAP 最小费用最大流:SPFA+增广(费用的值较离散) or ZKW(费用的值集中) 有源汇的上下界最大流:新建s', t',用(i, j, l, r)表示i到j有一条下界为l上界为r的边,将每条这样的边拆成(s', j, 0, l), (i, t', 0, l), (i, j, 0, r-l),加入边(t, s, 0, max)再从s'到t'求最大流,再去掉(t, s, 0, max)这条边,从s到t求最大流 有源汇的上下界最小可行流:基本同上,将最后一步改成从t到

hdu 3204(最小割--关键割边)

Ikki's Story I - Road Reconstruction Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 7491   Accepted: 2172 Description Ikki is the king of a small country – Phoenix, Phoenix is so small that there is only one city that is responsible fo

题单二:图论500

http://wenku.baidu.com/link?url=gETLFsWcgddEDRZ334EJOS7qCTab94qw5cor8Es0LINVaGMSgc9nIV-utRIDh--2UwRLvsvJ5tXFjbdpzbjygEdpGehim1i5BfzYgYWxJmu ==========  以下是最小生成树+并查集=========================[HDU]1213         How Many Tables        基础并查集★1272         小

图论五百题!

生死看淡不服就淦,这才是人生! =============================以下是最小生成树+并查集======================================[HDU]1213 How Many Tables 基础并查集★1272 小希的迷宫 基础并查集★1325&&poj1308 Is It A Tree? 基础并查集★1856 More is better 基础并查集★1102 Constructing Roads 基础最小生成树★1232 畅通工程 基