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


    最小割....

    ---------------------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cctype>
     
    #define rep( i , n ) for( int i = 0 ; i < n ; ++i )
    #define clr( x , c ) memset( x , c , sizeof( x ) )
    #define Rep( i , n ) for( int i = 1 ; i <= n ; ++i )
     
    using namespace std;
     
    const int maxn = 300 + 5;
     
    struct edge {
    int to , cap;
    edge *next , *rev;
    };
     
    edge* pt;
    edge* head[ maxn ];
    edge EDGE[ maxn * maxn << 1 ];
     
    void init() {
    pt = EDGE;
    clr( head , 0 );
    }
     
    inline void add( int u , int v , int d ) {
    pt -> to = v;
    pt -> cap = d;
    pt -> next = head[ u ];
    head[ u ] = pt++;
    }
     
    inline void add_edge( int u , int v , int d ) {
    add( u , v , d );
    add( v , u , 0 );
    head[ u ] -> rev = head[ v ];
    head[ v ] -> rev = head[ u ];
    }
     
    edge *p[ maxn ] , *cur[ maxn ];
    int d[ maxn ] , cnt[ maxn ];
     
    int maxFlow( int S , int T , int N ) {
    clr( d , 0 );
    clr( cnt , 0 );
    cnt[ 0 ] = N;
    rep( i , N ) cur[ i ] = head[ i ];
    const int INF = 0x7fffffff;
    int x = S , flow = 0 , A = INF;
    edge* e;
    while( d[ S ] < N ) {
    for( e = cur[ x ] ; e ; e = e -> next )
       if( e -> cap > 0 && d[ e -> to ] + 1 == d[ x ] ) break;
       
    if( e ) {
    p[ e -> to ] = cur[ x ] = e;
    A = min( A , e -> cap );
    x = e -> to;
    if( x == T ) {
    while( x != S ) {
    p[ x ] -> cap -= A;
    p[ x ] -> rev -> cap += A;
    x = p[ x ] -> rev -> to;
    }
    flow += A;
    A = INF;
    }
    } else {
    if( ! --cnt[ d[ x ] ] ) break;
    d[ x ] = N;
    for( e = head[ x ] ; e ; e = e -> next ) if( d[ x ] > d[ e -> to ] + 1 && e -> cap > 0 ) {
    d[ x ] = d[ e -> to ] + 1;
    cur[ x ] = e;
    }
    cnt[ d[ x ] ]++;
    if( x != S ) x = p[ x ] -> rev -> to;
    }
    }
    return flow;
    }
     
    int main() {
    init();
    int n , m;
    cin >> n >> m;
    int s = 0 , t = n + 1;
    Rep( i , n ) {
    int x;
    scanf( "%d" , &x );
    x ? add_edge( s , i , 1 ) : add_edge( i , t , 1 );
    }
    while( m-- ) {
    int u , v;
    scanf( "%d%d" , &u , &v );
    add_edge( u , v , 1 );
    add_edge( v , u , 1 );
    }
    cout << maxFlow( s , t , t + 1 ) << " ";
    return 0;
    }

    ---------------------------------------------------------------------------------

    1934: [Shoi2007]Vote 善意的投票

    Time Limit: 1 Sec  Memory Limit: 64 MB
    Submit: 1316  Solved: 813
    [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

  • 相关阅读:
    Microsoft .NET 框架资源基础(摘自msdn)
    cache的应用
    cache应用(asp.net 2.0 + sqlserver2005 数据依赖缓存 )
    c#遍历查找指定文件
    各浏览器目前对CSS3、HTML5的支持
    一步步构建大型网站架构
    c#连接sqlserver数据库
    C#中如何判断一个字符是汉字
    c#执行DOC命令
    VS2010快捷键
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4526617.html
Copyright © 2020-2023  润新知