hdu3987(最小割最小边数)

来源:互联网 发布:java future.get 编辑:程序博客网 时间:2024/05/18 01:12

题目

题解:与hdu6214基本相同 传送门

题解:

#include<bits/stdc++.h>using namespace std;const int MAXN = 100010;//点数的最大值const int MAXM = 400010;//边数的最大值const int INF = 0x3f3f3f3f;#define ll long longstruct Edge{    int to,next;    ll cap,flow;} edge[MAXM]; //注意是MAXMint tol;int head[MAXN];int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];void init(){    tol = 0;    memset(head,-1,sizeof(head));}//加边,单向图三个参数,双向图四个参数void addedge(int u,int v,ll w,int rw=0){    edge[tol].to = v;    edge[tol].cap = w;    edge[tol].next = head[u];    edge[tol].flow = 0;    head[u] = tol++;    edge[tol].to = u;    edge[tol].cap = rw;    edge[tol].next = head[v];    edge[tol].flow = 0;    head[v]=tol++;}//输入参数:起点、终点、点的总数//点的编号没有影响,只要输入点的总数ll sap(int start,int end,int N){    memset(gap,0,sizeof(gap));    memset(dep,0,sizeof(dep));    memcpy(cur,head,sizeof(head));    int u = start;    pre[u] = -1;    gap[0] = N;    ll ans = 0;    while(dep[start] < N)    {        if(u == end)        {            int Min = INF;            for(int i = pre[u]; i != -1; i = pre[edge[i^1].to])                if(Min > edge[i].cap - edge[i].flow)                    Min = edge[i].cap - edge[i].flow;            for(int i = pre[u]; i != -1; i = pre[edge[i^1].to])            {                edge[i].flow += Min;                edge[i^1].flow -= Min;            }            u = start;            ans += Min;            continue;        }        bool flag = false;        int v;        for(int i = cur[u]; i != -1; i = edge[i].next)        {            v = edge[i].to;            if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u])            {                flag = true;                cur[u] = pre[v] = i;                break;            }        }        if(flag)        {            u = v;            continue;        }        int Min = N;        for(int i = head[u]; i != -1; i = edge[i].next)            if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)            {                Min = dep[edge[i].to];                cur[u] = i;            }        gap[dep[u]]--;        if(!gap[dep[u]])return ans;        dep[u] = Min+1;        gap[dep[u]]++;        if(u != start) u = edge[pre[u]^1].to;    }    return ans;}int main(){    int t,n,m,vs,vt,flag,ca=1;;    scanf("%d",&t);    while (t--)    {        init();        scanf("%d %d",&n,&m);        //vs=0,vt=1;        for(int i=0;i<m;i++)        {            int u,v,w;            scanf("%d %d %d %d",&u,&v,&w,&flag);            addedge(u,v,(ll)w*MAXM+1);            if(flag)addedge(v,u,(ll)w*MAXM+1);        }        ll ans = sap(0,n-1,n)%MAXM;        printf("Case %d: %lld\n",ca++,ans);    }    return 0;}
原创粉丝点击