zoukankan      html  css  js  c++  java
  • poj 2699 The Maximum Number of Strong Kings【最大流+枚举】

    因为n很小所以从大到小枚举答案。(从小到大先排个序,因为显然胜利场次越多越容易成为strong king。然后对于每个枚举出来的ans建图。点分别表示人和比赛。s向所有人连接流量为胜利场次的边,所有比赛向t连流量为1的边来限制流量,然后对于“某一方一定要赢得比赛”,也就是当前被枚举为strong king一定要赢比他赢得场次多(注意是严格大于,要把等于判掉)的人,这种情况,把一定要赢的人向这场比赛连流量为1的边。否则比赛双方都向该比赛连边,表示谁赢都可以。然后跑dinic,看最大流是否等于比赛场次。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<queue>
    #include<algorithm>
    using namespace std;
    const int N=505,inf=1e9;
    int T,n,h[N],cnt,a[N],ans,s,t,sum,le[N],id[N][N];
    string c;
    struct qwe
    {
    	int ne,to,v;
    }e[N];
    void add(int u,int v,int w)
    {
    	cnt++;
    	e[cnt].ne=h[u];
    	e[cnt].to=v;
    	e[cnt].v=w;
    	h[u]=cnt;
    }
    void ins(int u,int v,int w)
    {
    	add(u,v,w);
    	add(v,u,0);
    }
    bool bfs()
    {
    	queue<int>q;
    	memset(le,0,sizeof(le));
    	le[s]=1;
    	q.push(s);
    	while(!q.empty())
    	{
    		int u=q.front();
    		q.pop();
    		for(int i=h[u];i;i=e[i].ne)
    			if(!le[e[i].to]&&e[i].v>0)
    			{
    				le[e[i].to]=le[u]+1;
    				q.push(e[i].to);
    			}
    	}
    	return le[t];
    }
    int dfs(int u,int f)
    {
    	if(u==t||!f)
    		return f;
    	int us=0;
    	for(int i=h[u];i&&us<f;i=e[i].ne)
    		if(le[e[i].to]==le[u]+1&&e[i].v>0)
    		{
    			int t=dfs(e[i].to,min(e[i].v,f-us));
    			e[i].v-=t;
    			e[i^1].v+=t;
    			us+=t;
    		}
    	if(!us)
    		le[u]=0;
    	return us;
    }
    int dinic()
    {
    	int re=0;
    	while(bfs())
    		re+=dfs(s,inf);
    	return re;
    }
    int main()
    {
    	scanf("%d
    ",&T);
    	while(T--)
    	{
    		n=0;
    		getline(cin,c);
    		for(int i=c.size()-1;i>=0;)
    		{
    			while((c[i]>'9'||c[i]<'0')&&i>=0)
    				i--;
    			int r=0;
    			while(c[i]>='0'&&c[i]<='9'&&i>=0)
    			{
    				r=r*10+c[i]-48;
    				i--;
    			}
    			a[++n]=r;
    		} 
    		sum=n;
    		sort(a+1,a+1+n);
    		for(int i=1;i<n;i++)
    			for(int j=i+1;j<=n;j++)
    				id[i][j]=++sum;
    		s=0,t=++sum;
    		for(ans=n;ans>=1;ans--)
    		{
    			memset(h,0,sizeof(h));
    			cnt=1;
    			for(int i=1;i<=n;i++)
    				ins(s,i,a[i]);
    			for(int i=1;i<n;i++)
    				for(int j=i+1;j<=n;j++)
    					ins(id[i][j],t,1);
    			for(int i=1;i<n;i++)
    				for(int j=i+1;j<=n;j++)
    				{
    					if(i>n-ans&&a[i]!=a[j]) 
    						ins(i,id[i][j],1);
    					else 
    					{
    						ins(i,id[i][j],1);
    						ins(j,id[i][j],1);
    					}
    				}
    			if(dinic()==n*(n-1)/2)
    			{
    				printf("%d
    ",ans);
    				break;
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    反转链表 16
    CodeForces 701A Cards
    hdu 1087 Super Jumping! Jumping! Jumping!(动态规划)
    hdu 1241 Oil Deposits(水一发,自我的DFS)
    CodeForces 703B(容斥定理)
    poj 1067 取石子游戏(威佐夫博奕(Wythoff Game))
    ACM 马拦过河卒(动态规划)
    hdu 1005 Number Sequence
    51nod 1170 1770 数数字(数学技巧)
    hdu 2160 母猪的故事(睡前随机水一发)(斐波那契数列)
  • 原文地址:https://www.cnblogs.com/lokiii/p/8385931.html
Copyright © 2011-2022 走看看