码迷,mamicode.com
首页 > 其他好文 > 详细

poj 3204 Ikki's Story I - Road Reconstruction

时间:2016-02-12 23:20:25      阅读:381      评论:0      收藏:0      [点我收藏+]

标签:

Ikki‘s Story I - Road Reconstruction

题意:有N个顶点和M条边N, M (N ≤ 500, M ≤ 5,000)  ,试图改变图中的一条边使得从0到N-1的流量增加;问这样的边有几条?

思路:刚最大流入门,之后一看就觉得满流的边就是答案。。真是太天真了。之后看了题解,发现满流只是前提(即使满流是几次残量的叠加也是一样),还有一个条件是,该路径的最大流量只受该边影响;即可以从S和T遍历到该边的两个端点,这就是为什么之后还要dfs给点涂色的原因;涂色前要对残余网络中输入的边(反向边不管)标记重建图;

 

技术分享
// 125ms
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<stack>
#include<set>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a))
#define inf 0x3f3f3f3f
#define pb push_back
#define MK make_pair
typedef pair<int,int> PII;
#define A first
#define B second
template<typename T>
void read1(T &m)
{
    T x=0,f=1;char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
    m = x*f;
}
template<typename T>
void read2(T &a,T &b){read1(a);read1(b);}
template<typename T>
void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
template<typename T>
void out(T a)
{
    if(a>9) out(a/10);
    putchar(a%10+0);
}
const int M = 5050;
const int N = 550;
int head[M<<1],tot;
struct edge{
    int from,to,cap,flow,Next;
}e[M<<1];
void ins(int u,int v,int cap,int flow)
{
    e[tot].Next = head[u];
    e[tot].from = u;//为了t->s时由v推到u;
    e[tot].to = v;
    e[tot].cap = cap;
    e[tot].flow = flow;
    head[u] = tot++;
}
queue<int> q;
vector<int> full;
int p[N];//记录路径中边的标号
int a[N];//起点到i的可改进量
void Edmonds_Karp(int s,int t)
{
    for(;;){
        MS0(a);
        while(!q.empty()) q.pop();
        a[s] = inf;
        q.push(s);
        while(!q.empty()){
            int u = q.front();q.pop();
            for(int id = head[u];~id;id = e[id].Next){
                int v = e[id].to,c = e[id].cap,f = e[id].flow;
                if(!a[v] && c > f){
                    p[v] = id;
                    a[v] = min(a[u],c - f);// ** 递推到a[v]
                    q.push(v);
                }
            }
            if(a[t]) break;
        }
        if(!a[t]) break;
        for(int u = t;u != s;u = e[p[u]].from){
            e[p[u]].flow += a[t];
            e[p[u]^1].flow -= a[t];
            if(e[p[u]].flow == e[p[u]].cap) full.pb(p[u]);
        }
    }
}
int color[N],V;
void DFS(int u,int index)
{
    if(~color[u]) return ;
    color[u] = index;
    for(int id = head[u];~id;id = e[id].Next){
        if(id&1 || e[id].flow == e[id].cap) continue;//只在原边中找,不看反向边;
        DFS(e[id].to,index);
    }
}
int solve()
{
    MS1(color);
    DFS(0,0);DFS(V-1,1);
    int ans = 0;
    rep0(i,0,full.size()){
        int u = e[full[i]].from, v = e[full[i]].to;
        if(color[u] == 0 && color[v] == 1){
            ans++;
            //out(u);putchar(‘ ‘);out(v);puts("bug");
        }
    }
    return ans;
}
int main()
{
    int n,E,kase = 1;
    read2(V,E);
    MS1(head);tot = 0;
    rep0(i,0,E){
        int u,v,w;
        read3(u,v,w);
        ins(u,v,w,0);ins(v,u,0,0);
    }
    Edmonds_Karp(0,V-1);
    out(solve());
    puts("");
    return 0;
}
View Code

 

poj 3204 Ikki's Story I - Road Reconstruction

标签:

原文地址:http://www.cnblogs.com/hxer/p/5187328.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!