zoukankan      html  css  js  c++  java
  • 洛谷 P2057 [SHOI2007]善意的投票

    题目链接

    考察网络流建图,从最小割的角度考虑比较容易

    改写一下题意:

    一张图,每个点初始有0/1两个值中的一个,现在让你重新赋值,变化其中一些点的值(还是0/1),使得新图里 相邻两点值不同的对数 加上 新图里点值与原图不同的点数量 的和最小

    相当于我们原来有一张图,里面的点分属两个集合,先改变(x)个点,使它们所处集合变化,得到新的集合划分,此时原图有(y)条边的端点分属不同集合

    求最小(x+y)

    这样转化一下,题目就有了网络流的雏形

    先看(y),很明显像最小割,我们只要让两个集合分别包含源点/汇点,端点分属两集合的边就是最小割里割去的边

    设流量为1,(y)就是最小割

    然后看(x),假设值为0属于源点集合,值为1属于汇点集合

    对于值为0的点,跟源点连容量为1的边,跟汇点连容量为0的边(等于不连边),

    这样,我们把该点划分到源点集合,割掉与汇点相连的边,代价是0,反过来代价是1,符合题意

    其余同理

    这样我们就建好了图,跑网络流即可

    [code]

    
    #include <bits/stdc++.h>
    using namespace std;
    
    int read(){
    	int x=0,flag=1; char c;
    	for(c=getchar();!isdigit(c);c=getchar()) if(c=='-') flag=-1;
    	for(;isdigit(c);c=getchar()) x=((x+(x<<2))<<1)+(c^48);
    	return x*flag;
    }
    
    const int N=350;
    
    int S,T,n,m;
    
    struct Edge{
        int to,next,v;
    }edge[N*N*2];
    int head[N];
    int tmp=-1;
    
    void add_edge(int x,int y,int z){
        ++tmp;
        edge[tmp].to=y; edge[tmp].next=head[x]; edge[tmp].v=z;
        head[x]=tmp;
    }
    
    void add(int x,int y,int z){
        add_edge(x,y,z); add_edge(y,x,0);
    }
    
    int dep[N];
    int cur[N];
    
    bool bfs(){
        queue<int> q;
        memset(dep,-1,sizeof(dep));
        q.push(S); dep[S]=0;
        while(!q.empty()){
    	    int f=q.front(); q.pop();
    	    for(int i=head[f];i!=-1;i=edge[i].next)
    		if(edge[i].v){
    		    int t=edge[i].to;
    		    if(dep[t]!=-1) continue;
    		    dep[t]=dep[f]+1;
    		    q.push(t);
    		}
    	}
    	return dep[T]!=-1;
    }
    
    int dfs(int nod,int val){
        if(!val||nod==T) return val;
        int flow=0;
    	for(int i=head[nod];i!=-1;i=edge[i].next)
    	if(edge[i].v){
    	    int t=edge[i].to;
    	    if(dep[t]!=dep[nod]+1) continue;
    	    int x=dfs(t,min(val,edge[i].v));
    	    val-=x; edge[i].v-=x;
    	    edge[i^1].v+=x; flow+=x;
    	    if(!val) break;
    	}
    	return flow;
    }
    
    int Dinic(){
        int ret=0;
        while(bfs()){
    	    memcpy(cur,head,sizeof(head));
    	    ret+=dfs(S,99999999);
    	}
    	return ret;
    }
    
    int main() {
        memset(head,-1,sizeof(head));
        n=read(),m=read();
        S=0; T=n+1;
        for(int i=1;i<=n;i++) { int x=read(); if(x==0) add(i,T,1); else add(S,i,1); } 
        for(int i=1;i<=m;i++){
    	    int x=read(),y=read();
    	    add(x,y,1); add(y,x,1);
    	}
    	printf("%d
    ",Dinic());
    	return 0;
    }
    
    
    
  • 相关阅读:
    json的相关知识
    实现highcharts放大缩小
    js总结
    sql语句学习
    关于echarts生成雷达图的一些参数介绍
    在表单导航中如何判断其进行到第几步
    IDEA的相关使用-----快捷键
    简单安装squid步骤
    feign调用文件上传服务,传参MultipartFile
    java.lang.IllegalStateException: Failed to load property source from location 'classpath:/application.yml'
  • 原文地址:https://www.cnblogs.com/zzhzzh123/p/12208484.html
Copyright © 2011-2022 走看看