BZOJ 1934: [Shoi2007]Vote 善意的投票

来源:互联网 发布:gs与js防水涂料的区别 编辑:程序博客网 时间:2024/06/07 23:44

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1934

求图的最小割=求一下图的最大流。


#include <iostream>#include <stdio.h>#include <queue>#include <string.h>using namespace std;const int INF = 0x3f3f3f3f;int cap[305][305],level[305],vis[305],a[305];int maxFlow,minFlow,minFlowNode;int N,M;   ///人数和关系数。int S,T;   ///S表示赞成,T表示反对bool bfs()  ///对图的节点进行分层{    queue<int>qu;    memset(level,-1,sizeof(level));    level[S] = 0;    qu.push(S);    while(!qu.empty())    {        int u = qu.front();        qu.pop();        for(int i = 0; i <= T; i++)        {            if(level[i] == -1 && cap[u][i]>0)            {                level[i] = level[u] + 1;                if(i == T)                    return true;                qu.push(i);            }        }    }    return false;}void dfs(){    int u,v,cur,i;    deque<int>qu;     ///双端队列,可以当作栈来用    memset(vis,0,sizeof(vis));    vis[S] = 1;    qu.push_back(S);    while(!qu.empty())    {        cur = qu.back();        if(cur == T)        {            minFlow = INF+1;            minFlowNode = S;            for(i = 1; i < qu.size(); i++)            {                u = qu[i-1];                v = qu[i];                if(cap[u][v]>0 && minFlow>cap[u][v])                {                    minFlow = cap[u][v];                    minFlowNode = u;                }            }            maxFlow += minFlow;            for(i = 1; i < qu.size(); i++)            {                u = qu[i-1];                v = qu[i];                cap[u][v] -= minFlow;                cap[v][u] += minFlow;            }            while(!qu.empty() && qu.back() != minFlowNode)            {                vis[qu.back()] = 0;                qu.pop_back();            }        }        else        {            for(i = 1; i <= T; i++)            {                if(cap[cur][i] > 0 && level[i]==level[cur]+1 && vis[i]==0)                {                    vis[i] = 1;                    qu.push_back(i);                    break;                }            }            if(i > T)                qu.pop_back();        }    }}void dinic(){    maxFlow = 0;    while(bfs())    {        dfs();    }}int main(){    while(~scanf("%d%d",&N,&M))    {        memset(cap,0,sizeof(cap));        int x,y;        S = 0;        T = N+1;        for(int i = 1; i <= N; i++)        {            scanf("%d",&x);            if(x == 1)                cap[S][i] = 1;            else                cap[i][T] = 1;        }        for(int i = 1; i <= M; i++)        {            scanf("%d%d",&x,&y);            cap[x][y] = cap[y][x] = 1;        }        dinic();        printf("%d\n",maxFlow);    }    return 0;}