nyoj 667 碟战 最小割(最大流)

来源:互联网 发布:中国第四人口普查数据 编辑:程序博客网 时间:2024/06/15 18:07

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=677

题意转化:将点0与所有的有间谍的点相连,则题意变为求点0到点n的最小割,直接套最大流EK算法~

下面代码顶点是从1~n+1

代码入下:

 #include "stdio.h"#include "string.h"#include "queue"using namespace std;#define N 205#define INF 0x3fffffffint start,end;int route[N],dis[N];int map[N][N];int MIN(int x,int y){ return x<y?x:y; }int BFS(){    int i;    int x,y;    memset(route,-1,sizeof(route));    dis[start] = INF;    queue<int> q;    q.push(start);    while(!q.empty())    {        x = q.front();        q.pop();        for(y=1; y<=end; ++y)        {            if(route[y]==-1 && map[x][y]!=0)            {                route[y] = x;                dis[y] = MIN(dis[x],map[x][y]);                q.push(y);            }        }    }    if(route[end]==-1) return 0;    return dis[end];}int EK(int n){    int x,y;    int ans=0;    int kejia;    while(kejia = BFS())    {        ans += kejia;        y = end;        while(y!=start)        {            x = route[y];            map[x][y] -= kejia;            map[y][x] += kejia;            y = x;        }    }    return ans;}int main(){    int T,Case;    int i,k;    int n,m,p;    int x,y;    scanf("%d",&T);    for(Case=1; Case<=T; ++Case)    {        memset(map,0,sizeof(map));        scanf("%d%d%d",&n,&m,&p);        for(i=0; i<p; ++i)        {            scanf("%d",&k);            k++;            map[1][k] = map[k][1] = INF;        }        while(m--)        {            scanf("%d %d",&x,&y);            x++; y++;            map[x][y] = map[y][x] = 1;        }        start = 1; end = n+1;        printf("Case #%d: %d\n",Case,EK(end));    }}        


0 0
原创粉丝点击