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

题目链接: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 0x3fffffff


int 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));
    }
}

        


你可能感兴趣的:(最大流)