zoukankan      html  css  js  c++  java
  • BZOJ2400: Spoj 839 Optimal Marks

    Description

    定义无向图中的一条边的值为:这条边连接的两个点的值的异或值。
    定义一个无向图的值为:这个无向图所有边的值的和。
    给你一个有n个结点m条边的无向图。其中的一些点的值是给定的,而其余的点的值由你决定(但要求均为非负数),使得这个无向图的值最小。在无向图的值最小的前提下,使得无向图中所有点的值的和最小。
     

    Input

    第一行,两个数n,m,表示图的点数和边数。
    接下来n行,每行一个数,按编号给出每个点的值(若为负数则表示这个点的值由你决定,值的绝对值大小不超过10^9)。
    接下来m行,每行二个数a,b,表示编号为a与b的两点间连一条边。(保证无重边与自环。)
     

    Output

        第一行,一个数,表示无向图的值。
        第二行,一个数,表示无向图中所有点的值的和。
     

    Sample Input

    3 2
    2
    -1
    0
    1 2
    2 3

    Sample Output

    2
    2

    HINT

    数据约定

      n<=500,m<=2000

     

    样例解释

    2结点的值定为0即可。

    经典的最小割建模。
    先按位处理,然后规定S割的节点表示选1,T割的节点表示选0。
    然后对那些权值固定的点强制连上inf,无向图的边也连上,最小割即可。
    第二问就是S割中的节点个数。
    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define ren for(int i=first[x];i!=-1;i=next[i])
    using namespace std;
    const int BufferSize=1<<16;
    char buffer[BufferSize],*head,*tail;
    inline char Getchar() {
        if(head==tail) {
            int l=fread(buffer,1,BufferSize,stdin);
            tail=(head=buffer)+l;
        }
        return *head++;
    }
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=510;
    const int maxm=10010;
    const int inf=1e9;
    struct Dinic {
        int n,m,s,t,cur[maxn],d[maxn],vis[maxn],clo;
        int first[maxn],next[maxm];
        struct Edge {int from,to,flow;}edges[maxm];
        void init(int n) {
            this->n=n;m=0;
            memset(first,-1,sizeof(first));
        }
        void AddEdge(int u,int v,int w) {
            edges[m]=(Edge){u,v,w};next[m]=first[u];first[u]=m++;
            edges[m]=(Edge){v,u,0};next[m]=first[v];first[v]=m++;
        }
        int Q[maxn];
        int BFS() {
            int l=0,r=0;Q[r++]=s;vis[s]=++clo;
            while(l!=r) {
                int x=Q[l++];cur[x]=first[x];
                ren {
                    Edge& e=edges[i];
                    if(e.flow&&vis[e.to]!=clo) {
                        vis[e.to]=clo;
                        d[e.to]=d[x]+1;
                        Q[r++]=e.to;
                    }
                }
            }
            return vis[t]==clo;
        }
        int DFS(int x,int a) {
            if(x==t||!a) return a;
            int flow=0,f;
            for(int& i=cur[x];i!=-1;i=next[i]) {
                Edge& e=edges[i];
                if(d[e.to]==d[x]+1&&(f=DFS(e.to,min(a,e.flow)))) {
                    e.flow-=f;edges[i^1].flow+=f;
                    flow+=f;a-=f;if(!a) break;
                }
            }
            return flow;
        }
        int solve(int s,int t) {
            this->s=s;this->t=t;int flow=0;
            while(BFS()) flow+=DFS(s,1e9);
            return flow;
        }
        int solve2() {
            BFS();int res=-1;
            rep(i,1,n) if(vis[i]==clo) res++;
            return res;
        }
    }sol;
    typedef long long ll;
    int val[maxn],u[maxm],v[maxm];
    ll ans,ans2;
    int main() {
        int n=read(),m=read();
        rep(i,1,n) val[i]=read();
        rep(i,1,m) u[i]=read(),v[i]=read();
        rep(i,0,30) {
            int S=n+1,T=n+2,sum=0;sol.init(T);
            rep(j,1,n) if(val[j]>=0) {
                if(val[j]>>i&1) sol.AddEdge(S,j,inf);
                else sol.AddEdge(j,T,inf);
            }
            rep(j,1,m) sol.AddEdge(u[j],v[j],1),sol.AddEdge(v[j],u[j],1);
            ans+=(1ll<<i)*sol.solve(S,T);
            ans2+=(1ll<<i)*sol.solve2();
        }
        printf("%lld
    %lld
    ",ans,ans2);
        return 0;
    }
    View Code
  • 相关阅读:
    KVC(key value coding)/ KVO(key value observing)
    手势识别
    导航控制器掌握内容:
    火车入轨_算法
    卡片游戏_算法
    Python合集之Python循环语句(一)
    Python合集之Python选择语句(四)
    Python合集之Python选择语句(三)
    Python合集之Python选择语句(二)
    Python合集之Python选择语句(一)
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/5288134.html
Copyright © 2011-2022 走看看