• 【poj2699】 The Maximum Number of Strong Kings


    http://poj.org/problem?id=2699 (题目链接)

    题意

      给出1张有向完全图。U->V表示U可以打败V并得一分。如果一个人的得分最高,或者他打败所有比自己得分高的人,那么此人就是king。现在按顺序给出每个人的得分,求最多可能有多少个king同时存在。

    Solution

      想了半天贪心,然而得分相等的情况真的很不好处理。。真的没想到是最大流。。左转题解:http://blog.csdn.net/sdj222555/article/details/7797257

      考虑这样建图的正确性。

      借用题解的example,假设序列长成这样:1....i......n。那么i不是king有以下这几种情况

      1.i的得分少于得分比它大的人的个数

      这种情况显然i不可能赢所有得分比它大的人,那么这如何在我们所构建的图上体现呢?

      对于i与得分比i大的人的比赛,从i连向它们,显然,这些边不可能满流,因为i不可能赢这么多场,于是不成立。

      2.n已经无法给予i赢的机会

      因为得分比i大的人想要成为King,必须赢得得分比他们更大的人n,而n能够输的场次是有限的。

      如果从i连向(i,n)的比赛使i强行赢得胜利,会使得边(s,n)不满流,于是不成立。

      也许还有别的情况我没考虑到,唉最近思维僵化,没救了,如果有补充请提出╮(╯_╰)╭

    细节

      多组数据注意初始化,为什么我还是要16ms。。自带常数。。

    代码

    // poj2699
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #define LL long long
    #define inf 2147483640
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
    
    const int maxn=1010;
    struct edge {int to,next,w;}e[maxn];
    int head[maxn],d[maxn],f[20][20],a[maxn],Max;
    int n,m,ans,cnt=1,es,et;
    char ch[maxn];
    
    void link(int u,int v,int w) {
    	e[++cnt]=(edge){v,head[u],w};head[u]=cnt;
    	e[++cnt]=(edge){u,head[v],w};head[v]=cnt;
    }
    void read() {
    	gets(ch);
    	n=m=Max=0;int l=strlen(ch);
    	for (int i=0;i<l;i++) if (ch[i]>='0' && ch[i]<='9') {
    			m=m*10+ch[i]-'0';
    			if (i==l || ch[i+1]<'0' || ch[i+1]>'9') a[++n]=m,m=0,Max=max(Max,a[n]);
    		}
    	for (int i=1;i<=n;i++)
    		for (int j=i+1;j<=n;j++) f[i][j]=f[j][i]=++m;
    	es=n+m+1;et=es+1;
    }
    void Init() {
    	cnt=ans=0;
    	memset(head,0,sizeof(head));
    }
    bool bfs() {
    	memset(d,-1,sizeof(d));
    	queue<int> q;q.push(es);d[es]=0;
    	while (!q.empty()) {
    		int x=q.front();q.pop();
    		for (int i=head[x];i;i=e[i].next) if (e[i].w && d[e[i].to]<0) {
    				d[e[i].to]=d[x]+1;
    				q.push(e[i].to);
    			}
    	}
    	return d[et]>0;
    }
    int dfs(int x,int f) {
    	if (x==et || f==0) return f;
    	int used=0,w;
    	for (int i=head[x];i;i=e[i].next) if (e[i].w && d[e[i].to]==d[x]+1) {
    			w=dfs(e[i].to,min(e[i].w,f-used));
    			used+=w;
    			e[i].w-=w;e[i^1].w+=w;
    			if (used==f) return used;
    		}
    	if (!used) d[x]=-1;
    	return used;
    }
    void Dinic() {
    	while (bfs()) ans+=dfs(es,inf);
    }
    int main() {
    	int T;scanf("%d",&T);getchar();
    	while (T--) {
    		read();
    		for (int s=1;s<=n;s++) {
    			Init();
    			for (int i=1;i<=n;i++) link(es,i,a[i]);
    			for (int i=1;i<s;i++)
    				for (int j=i+1;j<=n;j++) link(i,f[i][j]+n,1),link(j,f[i][j]+n,1);
    			for (int i=s;i<=n;i++)
    				for (int j=i+1;j<=n;j++) {
    					link(i,f[i][j]+n,1);
    					if (a[i]==Max) link(j,f[i][j]+n,1);
    				}
    			for (int i=n+1;i<=n+m;i++) link(i,et,1);
    			Dinic();
    			if (ans==m) {printf("%d
    ",n-s+1);break;}
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    深入Android 【一】 —— 序及开篇
    Android中ContentProvider和ContentResolver使用入门
    深入Android 【六】 —— 界面构造
    The service cannot be activated because it does not support ASP.NET compatibility. ASP.NET compatibility is enabled for this application. Turn off ASP.NET compatibility mode in the web.config or add the AspNetCompatibilityRequirements attribute to the ser
    Dynamic Business代码片段总结
    对文件的BuildAction以content,resource两种方式的读取
    paraview 3.12.0 windows下编译成功 小记
    百度网盘PanDownload使用Aria2满速下载
    netdata的安装与使用
    用PS给证件照排版教程
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/6216133.html
Copyright © 2020-2023  润新知