程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> BZOJ 1934([Shoi2007]Vote 善意的投票-最小割)

BZOJ 1934([Shoi2007]Vote 善意的投票-最小割)

編輯:C++入門知識

[Submit][Status][Discuss]
Description
幼兒園裡有n個小朋友打算通過投票來決定睡不睡午覺。對他們來說,這個問題並不是很重要,於是他們決定發揚謙讓精神。雖然每個人都有自己的主見,但是為了照顧一下自己朋友的想法,他們也可以投和自己本來意願相反的票。我們定義一次投票的沖突數為好朋友之間發生沖突的總數加上和所有和自己本來意願發生沖突的人數。 我們的問題就是,每位小朋友應該怎樣投票,才能使沖突數最小?
Input
第一行只有兩個整數n,m,保證有2≤n≤300,1≤m≤n(n-1)/2。其中n代表總人數,m代表好朋友的對數。文件第二行有n個整數,第i個整數代表第i個小朋友的意願,當它為1時表示同意睡覺,當它為0時表示反對睡覺。接下來文件還有m行,每行有兩個整數i,j。表示i,j是一對好朋友,我們保證任何兩對i,j不會重復。
Output
只需要輸出一個整數,即可能的最小沖突數。
Sample Input
3 3
1 0 0
1 2
1 3
3 2

Sample Output
1
HINT
在第一個例子中,所有小朋友都投贊成票就能得到最優解

Source
Day2

[Submit][Status][Discuss]
想到是最小割就好辦了呢。。。。(喂我沒想到啊混蛋)

S向贊成的小孩連,T向反對的連,好友互相連,容量皆為1

OK(根據最小割定義,最小割切的都是從S向T的有向邊【話外:反向呢?答:無視】,顯然成立)


[cpp]  #include<cstdio>  
#include<cstring>  
#include<cstdlib>  
#include<algorithm>  
#include<functional>  
#include<iostream>  
#include<cmath>  
#include<cctype>  
#include<ctime>  
using namespace std; 
#define For(i,n) for(int i=1;i<=n;i++)  
#define Fork(i,k,n) for(int i=k;i<=n;i++)  
#define Rep(i,n) for(int i=0;i<n;i++)  
#define ForD(i,n) for(int i=n;i;i--)  
#define RepD(i,n) for(int i=n;i>=0;i--)  
#define Forp(x) for(int p=pre[x];p;p=next[p])  
#define Lson (x<<1)  
#define Rson ((x<<1)+1)  
#define MEM(a) memset(a,0,sizeof(a));  
#define MEMI(a) memset(a,127,sizeof(a));  
#define MEMi(a) memset(a,128,sizeof(a));  
#define INF (2139062143)  
#define F (100000007)  
#define MAXN (300+2+10)  
#define MAXM (MAXN*MAXN*4)   
long long mul(long long a,long long b){return (a*b)%F;} 
long long add(long long a,long long b){return (a+b)%F;} 
long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;} 
int edge[MAXM],pre[MAXN]={0},next[MAXM],weight[MAXM],size=1; 
void addedge(int u,int v,int w) 

    edge[++size]=v; 
    weight[size]=w; 
    next[size]=pre[u]; 
    pre[u]=size; 

void addedge2(int u,int v,int w){addedge(u,v,w),addedge(v,u,0);} 
int d[MAXN]={0},cnt[MAXN]={0},s,t; 
int totflow=0; 
int sap(int x,int flow) 

    if (x==t) return flow; 
    int nowflow=0; 
    Forp(x) 
    { 
        int &v=edge[p]; 
        if (d[v]==d[x]-1&&weight[p]>0) 
        { 
            int fl=sap(v,min(flow,weight[p])); 
            weight[p]-=fl,weight[p^1]+=fl,flow-=fl,nowflow+=fl; 
            if (!flow) return nowflow; 
        } 
    } 
    if (!(--cnt[d[x]++])) d[s]=t+1; 
    cnt[d[x]]++; 
    return nowflow;  
}  
int n,m,a[MAXN]; 
int main() 

//  freopen("conflict.in","r",stdin);  
//  freopen("conflict.out","w",stdout);  
    scanf("%d%d",&n,&m); 
    s=n+1,t=s+1; 
    For(i,n)  
    { 
        scanf("%d",&a[i]); 
        if (a[i]) addedge2(s,i,1); 
        else addedge2(i,t,1); 
    } 
    For(i,m) 
    { 
        int u,v; 
        scanf("%d%d",&u,&v); 
        addedge(u,v,1);addedge(v,u,1); 
    } 
    cnt[0]=n+2; 
    while (d[s]<=t) totflow+=sap(s,INF); 
    cout<<totflow<<endl; 
 
    return 0; 

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define MAXN (300+2+10)
#define MAXM (MAXN*MAXN*4)
long long mul(long long a,long long b){return (a*b)%F;}
long long add(long long a,long long b){return (a+b)%F;}
long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
int edge[MAXM],pre[MAXN]={0},next[MAXM],weight[MAXM],size=1;
void addedge(int u,int v,int w)
{
 edge[++size]=v;
 weight[size]=w;
 next[size]=pre[u];
 pre[u]=size;
}
void addedge2(int u,int v,int w){addedge(u,v,w),addedge(v,u,0);}
int d[MAXN]={0},cnt[MAXN]={0},s,t;
int totflow=0;
int sap(int x,int flow)
{
 if (x==t) return flow;
 int nowflow=0;
 Forp(x)
 {
  int &v=edge[p];
  if (d[v]==d[x]-1&&weight[p]>0)
  {
   int fl=sap(v,min(flow,weight[p]));
   weight[p]-=fl,weight[p^1]+=fl,flow-=fl,nowflow+=fl;
   if (!flow) return nowflow;
  }
 }
 if (!(--cnt[d[x]++])) d[s]=t+1;
 cnt[d[x]]++;
 return nowflow;
}
int n,m,a[MAXN];
int main()
{
// freopen("conflict.in","r",stdin);
// freopen("conflict.out","w",stdout);
 scanf("%d%d",&n,&m);
 s=n+1,t=s+1;
 For(i,n)
 {
  scanf("%d",&a[i]);
  if (a[i]) addedge2(s,i,1);
  else addedge2(i,t,1);
 }
 For(i,m)
 {
  int u,v;
  scanf("%d%d",&u,&v);
  addedge(u,v,1);addedge(v,u,1);
 }
 cnt[0]=n+2;
 while (d[s]<=t) totflow+=sap(s,INF);
 cout<<totflow<<endl;

 return 0;
}


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved