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(); } }