HDU 3549 最大流纯模板

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3549
题意:T组样例,做点1–>n的最大流
规模:
(2 <= N <= 15, 0 <= M <= 1000)
(1 <= X, Y <= N, 1 <= C <= 1000)
类型:最大流基础,纯模板
分析:第一次做网络流,在代码里加了许多注释,边学边敲
时间复杂度&&优化:
朴素算法O(FE); 。F为遍历深度
dinic算法O(EV*V);。这里只写了dinic。
代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include

using namespace std;

const int MAX_N = 20;
const int MAX_M = 20005;
const int inf = 1000000007;
const int mod = 1000000007;

char s[20];
int n,m;

struct edge{
    int to;
    int cap;///容量
    int rev;///反向边,,记录这条边的from点
};
vector G[MAX_N];///图的邻接表表示
int level[MAX_N];///定点到源点的距离标号
int iter[MAX_N];///当前弧,在其之前的边已经没用了

///向图中增加一条从from到to的容量为cap的边;
void add_edge(int from,int to,int cap){
    G[from].push_back( (edge){to,cap,G[to].size()} );
    G[to].push_back((edge){from,0,G[from].size()-1});///这个-1是减上面行代码的干扰
}

///通过BFS计算从源点出发的距离标号
void bfs(int s){///正常bfs,以离s的距离进行编号
    memset(level ,-1,sizeof(level));///我是38
    level[s]=0;
    queue<int >que;
    que.push(s);
    while(!que.empty()){
        int v=que.front();que.pop();
        for(int i=0;i///???没道理取地址啊
            if(e.cap>0&&level[e.to]<0){
                level[e.to]=level[v]+1;
                que.push(e.to);
            }
        }
    }
    //for(int z=0;z
}

///通过DFS寻找增广路,,, 从v点发送f的流量到t,返回最大可发送量
int dfs(int v,int t,int f){///t不变,是真目标点.....
    if(v==t)return f;
    for(int &i=iter[v];i///???这里也有取地址
        edge &e=G[v][i];///当前弧,,
        ///原来优化在这里(上面两行)!:朴素算法重复计算了边G[V][0]~G[V][iter-1],而iter是当前弧!!
        if(e.cap>0&&level[v]int d=dfs(e.to,t,min(f,e.cap));
            if(d>0){
                e.cap-=d;
                G[e.to][e.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}

///求解从s到t的最大流
long long max_flow(int s,int t){
    long long flow=0;
    for(;;){///无限循环,理论推导可得循环上限O(EV*V),,朴素为O(F*E);
        bfs(s);
        if(level[t]<0)return flow;///找不到增广路就reutrn。看第38行代码
        memset(iter,0,sizeof(iter));///当前弧::存储下一个节点的编号
        int f;
        while((f=dfs(s,t,inf))>0){///这是个while!!!???::相比于朴素算法的for(;;),并没有什么区别,这个while是对前面几个初始化的保护。
            flow+=f;
        }
    }
}


int main()
{
    //freopen("test.txt","r",stdin);
    int T;
    cin>>T;
    for(int z=1;z<=T;z++){
        scanf("%d%d",&n,&m);
        for(int i=0;i<=n;i++) G[i].clear();///!!!清空数组G
        for(int i=0;iint a,b,c;
            cin>>a>>b>>c;
            a--;b--;
            add_edge(a,b,c);
        }

        long long k=max_flow(0,n-1);
        printf("Case %d: %I64d\n",z,k);
    }

    return 0;
}

你可能感兴趣的:(ACM算法,ACM题目,私人)