• BZOJ2768 [JLOI2010]冠军调查(Dinic算法求最小割)


    Description

    一年一度的欧洲足球冠军联赛已经进入了淘汰赛阶段。随着卫冕冠军巴萨罗那的淘汰,英超劲旅切尔西成为了头号

    热门。新浪体育最近在吉林教育学院进行了一次大规模的调查,调查的内容就是关于切尔西能否在今年问鼎欧洲冠

    军。新浪体育的记者从各个院系中一共抽取了n位同学作为参与者,大家齐聚一堂,各抒己见。每一位参与者都将

    发言,阐述自己的看法。参与者的心里都有一个看法,比如FireDancer认为切尔西不可能夺冠,而WaterDancer认

    为切尔西一定问鼎。但是因为WaterDancer是FireDancer的好朋友,所以可能FireDancer为了迁就自己的好朋友,

    会在发言中支持切尔西。也就是说每个参与者发言时阐述的看法不一定就是心里所想的。现在告诉你大家心里的想

    法和参与者的朋友网,希望你能安排每个人的发言内容,使得违心说话的人的总数与发言时立场不同的朋友(对)

    的总数的和最小。

    Input

    第一行两个整数n和m,其中n(2≤n≤300)表示参与者的总数,m(0≤m≤n(n-1)/2)表示朋友的总对数。

    第二行n个整数,要么是0要么是1。

    如果第i个整数的值是0的话,表示第i个人心里认为切尔西将与冠军无缘,

    如果是1的话,表示他心里认为切尔西必将夺魁。

    下面m行每行两个不同的整数,i和j(1≤i, j≤n)表示i和j是朋友。

    注意没有一对朋友会在输入中重复出现。朋友关系是双向的,并且不会传递。

    Output

    只有一个整数,为最小的和

     

    题解:

    源点向每个不喜欢切尔西的人连边。

    每个喜欢切尔西的人向终点连边。

    每对朋友之间连边。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+10;
    const int inf=1e9;
    int N,M;
    struct node {
        int u;
        int v;
        int w;
        int next;
    }edge[maxn];
    int head[maxn];
    int tol;
    void addedge (int u,int v,int w) {
        edge[tol].u=u;
        edge[tol].v=v;
        edge[tol].w=w;
        edge[tol].next=head[u];
        head[u]=tol++;
        edge[tol].u=v;
        edge[tol].v=u;
        edge[tol].w=w;
        edge[tol].next=head[v];
        head[v]=tol++;
    }
    
    
    int dep[maxn];
    int inque[maxn];
    int vi;
    int cur[maxn];
    int maxflow=0;
    int s,t;
    bool bfs () {
        for (int i=0;i<=N+1;i++) 
            cur[i]=head[i],dep[i]=inf,inque[i]=0;
        dep[s]=0;
        queue<int> q;
        q.push(s);
        while (!q.empty()) {
            int u=q.front();
            q.pop();
            inque[u]=0;
            for (int i=head[u];i!=-1;i=edge[i].next) {
                int v=edge[i].v;
                if (dep[v]>dep[u]+1&&edge[i].w) {
                    dep[v]=dep[u]+1;
                    if (inque[v]==0) {
                        q.push(v);
                        inque[v]=1;
                    } 
                }
            }
        }
        if (dep[t]!=inf) return 1;
        return 0;
    }
    int dfs (int u,int flow) {
        int increase=0;
        if (u==t) {
            vi=1;
            maxflow+=flow;
            return flow;
        }
        int used=0;
        for (int i=cur[u];i!=-1;i=edge[i].next) {
            cur[u]=i;
            int v=edge[i].v;
            if (edge[i].w&&dep[v]==dep[u]+1) {
                if (increase=dfs(v,min(flow-used,edge[i].w))) {
                    used+=increase;
                    edge[i].w-=increase;
                    edge[i^1].w+=increase;
                    if (used==flow) break;
                }
            }
        }
        return used;
    }
    int Dinic () {
        while (bfs()) {
            vi=1;
            while (vi==1) {
                vi=0;
                dfs(s,inf);
            }
        } 
        return maxflow;
    }
    int main () {
        scanf("%d%d",&N,&M);
        memset(head,-1,sizeof(head));
        s=0,t=N+1;
        for (int i=1;i<=N;i++) {
            int x;
            scanf("%d",&x);
            if (x==0) addedge(s,i,1);
            else addedge(i,t,1);
        }
        for (int i=1;i<=M;i++) {
            int x,y;
            scanf("%d%d",&x,&y);
            addedge(x,y,1);
        }
        printf("%d
    ",Dinic());
        return 0;
    }
  • 相关阅读:
    软件测试—— junit 单元测试
    falut error failure 的区别与理解
    错误的反思
    只能在微信浏览器打开的链接,如何查看源码
    PHPManage for IIS Windows 10
    wamp mysql配置
    CSS Flexbox 学习指南、工具与框架
    Android SDK 在线更新镜像服务器资源
    64位win2003 IIS6运行32位的.NET程序
    让服务器iis支持.apk文件下载的设置方法
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/12509515.html
Copyright © 2020-2023  润新知