POJ 2699 The Maximum Number of Strong Kings ——网络流

一定存在一种最优方案,使得分数前几个人是SK

所以我们可以二分答案或者枚举,然后就是经典的网络流建模。

另:输入很Excited

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>

#include <set>
#include <string>
#include <algorithm>
#include <vector>
#include <iostream>
#include <queue>

using namespace std;

#define F(i,j,k) for (int i=j;i<=k;++i)
#define maxn 1000005
#define inf (0x3f3f3f3f)

int read()
{
    int x=0,f=1; char ch=getchar();
    while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}

int m;
int a[101],S,T;

bool cmp(int a,int b)
{return a>b;}

int h[300001],to[300001],ne[300001],fl[300001],en=0;
int map[300001];

void add (int a,int b,int r)
{
	to[en]=b;
	fl[en]=r;
	ne[en]=h[a];
	h[a]=en++;
	to[en]=a;
	fl[en]=0;
	ne[en]=h[b];
	h[b]=en++;
}

int mp[300001];

bool tell()
{
    memset(mp,-1,sizeof mp);
    queue <int> q;
    while (!q.empty()) q.pop();
    q.push(S); mp[S]=0;
    while (!q.empty())
    {
        int x=q.front(); q.pop();
        for (int i=h[x];i>=0;i=ne[i])
        {
            if (fl[i]>0&&mp[to[i]]==-1)
            {
                mp[to[i]]=mp[x]+1;
                q.push(to[i]);
            }
        }
    }
    if (mp[T]==-1) return false;
    return true;
}

int zeng(int k,int now)
{
    if (k==T) return now;
    int ret=0;
    for (int i=h[k];i>=0&&ret<now;i=ne[i])
    {
        if (fl[i]>0&&mp[to[i]]==mp[k]+1)
        {
            int tmp=zeng(to[i],min(now-ret,fl[i]));
            fl[i]-=tmp; fl[i^1]+=tmp; ret+=tmp;
        }
    }
    if (ret==0) mp[k]=-1;
    return ret;
}

int dinic()
{
    int r=0,t;
    while (tell()) while (t=zeng(S,inf)) r+=t;
    return r; 
}

int hash[101][101],sum=0;

bool test(int mid)
{
	int cnt=a[0]; S=0;
	for (int i=1;i<=a[0];++i)
		for (int j=1;j<=a[0];++j)
			hash[i][j]=++cnt;
	T=++cnt;
	for (int i=1;i<=a[0];++i) add(S,i,a[i]);
	for (int i=1;i<=a[0];++i)
		for (int j=1;j<i;++j)
		if (j!=i){
			add(hash[i][j],T,1);
			if (a[i]<a[j]&&i<=mid) add(i,hash[i][j],1);
			else
			{
				add(i,hash[i][j],1);
				add(j,hash[i][j],1);
			}
		}
	int out=dinic();
	if (out>=sum) return true;
	else return false;
}

void init()
{
	memset(h,-1,sizeof h);
	en=0;
}

void solve()
{
	int l=1,r=a[0];
	while (l<r)
	{
		init();
		int mid=(l+r)/2+1;
		if (test(mid)) l=mid;
		else r=mid-1;
	}
	printf("%d\n",l);
}

char s[1000];

int main()
{
	cin>>m; gets(s);
	while (m--)
	{
		sum=0;
		cin.getline(s,100);
		int x=0; a[0]=0;
		for (int i=0;i<strlen(s);++i)
		{
			if (s[i]>='0'&&s[i]<='9')
				a[++a[0]]=s[i]-'0',sum+=a[a[0]];
		}
		a[++a[0]]=x; sum+=x;x=0;a[0]--;
		sort(a+1,a+a[0]+1,cmp);
		solve();
	}
}

  

posted @ 2017-03-30 18:08  SfailSth  阅读(128)  评论(0编辑  收藏  举报