hdu6214-最小割集中边数最少

来源:互联网 发布:手机淘宝活动报名 编辑:程序博客网 时间:2024/06/06 04:14

感觉题意好迷啊= =,读懂,就知道是模板题了。
求最小割集中边数最少,有两种解法,比赛中我用的第一种,据别人说第二种会超时,没测试过。hdu3987应该是两种都能用的。
第一种:
建边的时候每条边权 w = w * (E + 1) + 1; E为一大数
这样得到最大流 maxflow / (E + 1) ,最少割边数 maxflow % (E + 1)。
第二种:
建图,得到最大流后,图中边若满流,说明该边是最小割上的边
再建图,原则:满流的边改为容量为 1 的边,未满流的边改为容量 INF 的边,然后最大流即答案。

#include <algorithm>#include <cstring>#include <queue>#include <cstdio>using namespace std;const int MAXN = 500;const int MAXM = 5005;const int INF = 0x3f3f3f3f;int S,T;int n,m;int head[MAXN*2],top;int cur[MAXN*2];int level[MAXN*2];queue<int>q;struct the_edge{    int next,to,v,re;} edge[MAXM];int va[MAXN];int vb[MAXN];void init_edge(){    memset(head,-1,sizeof(head));    top=0;}void add_edge(int a,int b,int v){    edge[top].to=b;    edge[top].v=v;    edge[top].next=head[a];    head[a]=top++;    edge[top].to=a;    edge[top].v=0;    edge[top].next=head[b];    head[b]=top++;}bool bfs(){    memset(level,-1,sizeof(level));    level[S]=0;    q.push(S);    while(!q.empty())    {        int nown=q.front();        q.pop();        for(int i=head[nown]; i!=-1; i=edge[i].next)        {            if(!edge[i].v||level[edge[i].to]!=-1)                continue;            level[edge[i].to]=level[nown]+1;            q.push(edge[i].to);        }    }    return level[T]!=-1;}int dfs(int nown,int maxf){    if(nown==T)        return maxf;    int nowf=0,flow;    for(int &i=cur[nown]; i!=-1; i=edge[i].next)    {        if(!edge[i].v||                level[edge[i].to]!=level[nown]+1)continue;        if((flow=dfs(edge[i].to,min(maxf-nowf,edge[i].v)))!=0)        {            nowf+=flow;            edge[i].v-=flow;            edge[i^1].v+=flow;            if(nowf==maxf)return maxf;        }    }    return nowf;}int dinic(){    int ans=0;    while(bfs())    {        memcpy(cur,head,sizeof(cur));        ans+=dfs(S,INF);    }    return ans;}int main(){    int cas;    scanf("%d",&cas);    while(cas--)    {        init_edge();        scanf("%d%d",&n,&m);        scanf("%d%d",&S,&T);        for(int i=0; i<m; i++)        {            int a,b,c;            scanf("%d%d%d",&a,&b,&c);            add_edge(a,b,c*1005+1);        }        int putans = dinic() % 1005;        printf("%d\n",putans);    }    return 0;}
阅读全文
0 0
原创粉丝点击