BZOJ1934:[SHOI2007]善意的投票 & BZOJ2768:[JLOI2010]冠军调查——题解

https://www.lydsy.com/JudgeOnline/problem.php?id=1934

https://www.lydsy.com/JudgeOnline/problem.php?id=2768

幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉。对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神。虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来意愿相反的票。我们定义一次投票的冲突数为好朋友之间发生冲突的总数加上和所有和自己本来意愿发生冲突的人数。 我们的问题就是,每位小朋友应该怎样投票,才能使冲突数最小?

最小割模型,S表示睡午觉,T表示不睡,然后连就行了。

然后这道简单题竟然出现在了两个省选题里面……

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=350;
const int M=N*N+N;
const int INF=1e9;
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch==‘-‘;ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
struct node{
    int nxt,to,w;
}edge[M];
int head[N],cnt=-1,S,T;
void add(int u,int v,int w){
    edge[++cnt].to=v;edge[cnt].w=w;edge[cnt].nxt=head[u];head[u]=cnt;
}
int lev[N],cur[N],dui[N];
bool bfs(int m){
    int r=0;
    for(int i=1;i<=m;i++){
    lev[i]=-1;
    cur[i]=head[i];
    }
    dui[0]=S,lev[S]=0;
    int u,v;
    for(int l=0;l<=r;l++){
    u=dui[l];
    for(int e=head[u];e!=-1;e=edge[e].nxt){
        v=edge[e].to;
        if(edge[e].w>0&&lev[v]==-1){
        lev[v]=lev[u]+1;
        r++;
        dui[r]=v;
        if(v==T)return 1;
        }
    }
    }
    return 0;
}
int dinic(int u,int flow,int m){
    if(u==m)return flow;
    int res=0,delta;
    for(int &e=cur[u];e!=-1;e=edge[e].nxt){
    int v=edge[e].to;
    if(edge[e].w>0&&lev[u]<lev[v]){
        delta=dinic(v,min(edge[e].w,flow-res),m);
        if(delta>0){
        edge[e].w-=delta;
        edge[e^1].w+=delta;
        res+=delta;
        if(res==flow)break;
        }
    }
    }
    if(res!=flow)lev[u]=-1;
    return res;
}
int c[N];
int main(){
    memset(head,-1,sizeof(head));
    int n=read(),m=read();
    S=n+1,T=S+1;
    for(int i=1;i<=n;i++){
    if(c[i]=read())add(S,i,1),add(i,S,0);
    else add(i,T,1),add(T,i,0);
    }
    for(int i=1;i<=m;i++){
    int a=read(),b=read();
    if(c[b])swap(a,b);
    add(a,b,1),add(b,a,0);
    }
    int ans=0;
    while(bfs(T))ans+=dinic(S,INF,T);
    printf("%d\n",ans);
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/ +

+++++++++++++++++++++++++++++++++++++++++++

原文地址:https://www.cnblogs.com/luyouqi233/p/9060489.html

时间: 2025-01-11 13:14:21

BZOJ1934:[SHOI2007]善意的投票 & BZOJ2768:[JLOI2010]冠军调查——题解的相关文章

BZOJ2768: [JLOI2010]冠军调查

2768: [JLOI2010]冠军调查 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 484  Solved: 332[Submit][Status] Description 一 年一度的欧洲足球冠军联赛已经进入了淘汰赛阶段.随着卫冕冠军巴萨罗那的淘汰,英超劲旅切尔西成为了头号热门.新浪体育最近在吉林教育学院进行了一次大规 模的调查,调查的内容就是关于切尔西能否在今年问鼎欧洲冠军.新浪体育的记者从各个院系中一共抽取了n位同学作为参与者,大家齐聚

BZOJ-2768: [JLOI2010]冠军调查(超级裸的最小割)

2768: [JLOI2010]冠军调查 Time Limit: 10 Sec  Memory Limit: 128 MB Description 一年一度的欧洲足球冠军联赛已经进入了淘汰赛阶段.随着卫冕冠军巴萨罗那的淘汰,英超劲旅切尔西成为了头号热门.新浪体育最近在吉林教育学院进行了一次大规模的调查,调查的内容就是关于切尔西能否在今年问鼎欧洲冠军.新浪体育的记者从各个院系中一共抽取了n位同学作为参与者,大家齐聚一堂,各抒己见.每一位参与者都将发言,阐述自己的看法.参与者的心里都有一个看法,比如

[BZOJ2768][JLOI2010]冠军调查(最小割)

题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2768 分析: 如果一个点i认为是0,则连一条S->i,如果认为是1,则i->T 然后对于是朋友的两点i,j,连一条双向边i,j 然后跑最小割就行了 易得每个说违心话的点对最小割的贡献为1,是朋友的两点对最小割的贡献也是1

2768: [JLOI2010]冠军调查( 最小割 )

最小割... 怎么乱搞都可以 -------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define rep( i, n ) for( int i = 0; i < n; ++i ) #define R

bzoj 2768: [JLOI2010]冠军调查

1 #include<cstdio> 2 #include<iostream> 3 #define M 100000 4 #include<cstring> 5 using namespace std; 6 int cnt=1,head[M],next[10*M],u[10*M],v[10*M],n,m,d[M],q[M],ans; 7 void jia(int a1,int a2,int a3) 8 { 9 cnt++; 10 u[cnt]=a2; 11 v[cnt]

[SHOI2007]善意的投票

嘟嘟嘟 看数据范围,加上题中频繁提到的冲突,就可以想到算法是最小割. 1.同意睡觉的,源点就像他连一条容量为1的边.割掉它就代表他背叛了自己的意愿. 2.同理,不同意睡觉的,就像汇点连一条边. 3.考虑每一对朋友.如果两个朋友意见相反,就互相连一条容量为1的边,割掉其中的任意一条就代表朋友之间发生了冲突,代价为1.而且根据网络流性质,一定不会同时割掉这两条边. 4.如果一对朋友之间意见相同呢?其实还是建边还是和上面一样.因为如果割掉这条边的原因一定是其中一个人为了照顾和自己意见相反的其他朋友,而

p2057 [SHOI2007]善意的投票

传送门 分析 权值不同点之间连权值为1的边 起点向每个1,每个0向终点也连权值为1的边 跑最小割即可 代码 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cctype> #include<cmath> #include<cstdlib> #include<

JLOI2010 冠军调查 最小割

var b,f:array[0..100000] of longint; s,t,i,j,n,m,x,y:longint; l,h:array[0..1000]of longint; a:array[0..1000,0..1000]of longint; procedure bfs; var i,head,tail,x,y:longint; begin fillchar(b,sizeof(b),0); fillchar(h,sizeof(h),$7f); h[t]:=0; head:=1; ta

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

1934: [Shoi2007]Vote 善意的投票 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=1934 Description 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然每个人都有自己的主见,但是为了照顾一下自己朋友的想法,他们也可以投和自己本来意愿相反的票.我们定义一次投票的冲突数