POJ2699 The Maximum Number of Strong Kings (maxflow)

来源:互联网 发布:编程cim是做什么的 编辑:程序博客网 时间:2024/06/06 20:54

recently I’ve done a lot network flow problem and this is one of them

first of all , there is only 10 potential player who can be the king so we can iter them form
let’s talk about how to build the network,once we build the network with k kings we can check the maximum flow ,if it is equal to the number of all edges,so the network or the graph we build is correct

  1. link all matches i with the source capacity is 1
  2. link all the player with sink point ,capacity is 1
  3. for all match that involve player i,j ,
    1. the score of the smaller one is the king , we link match i with the smaller one , because the king of them must beat all the player whose score is higher than itself,and for that the result is established. Capacity is 1
    2. and the rest match m related to i,j we link both i,j,to match m also the cap i 1
      so this question become a max_flow problem!
#include <cstdio>#include <cstring>#include <stack>#include <cstring>#include <cctype>#define ll long longusing namespace std;const int INF=0x3f3f3f3f;const int MAXN=150;//点数的最大值const int MAXM=20500;//边数的最大值struct Node{    int from,to,next;    int cap;} edge[MAXM];int tol;int dep[MAXN];//dep为点的层次int head[MAXN];int n;void init(){    tol=0;    memset(head,-1,sizeof(head));}void addedge(int u,int v,int w)//第一条变下标必须为偶数{    edge[tol].from=u;    edge[tol].to=v;    edge[tol].cap=w;    edge[tol].next=head[u];    head[u]=tol++;    edge[tol].from=v;    edge[tol].to=u;    edge[tol].cap=0;    edge[tol].next=head[v];    head[v]=tol++;}int BFS(int start,int end){    int que[MAXN];    int front,rear;    front=rear=0;    memset(dep,-1,sizeof(dep));    que[rear++]=start;    dep[start]=0;    while(front!=rear)    {        int u=que[front++];        if(front==MAXN)front=0;        for(int i=head[u]; i!=-1; i=edge[i].next)        {            int v=edge[i].to;            if(edge[i].cap>0&&dep[v]==-1)            {                dep[v]=dep[u]+1;                que[rear++]=v;                if(rear>=MAXN)rear=0;                if(v==end)return 1;            }        }    }    return 0;}int dinic(int start,int end){    int res=0;    int top;    int stack[MAXN];//stack为栈,存储当前增广路    int cur[MAXN];//存储当前点的后继    while(BFS(start,end))    {        memcpy(cur,head,sizeof(head));        int u=start;        top=0;        while(1)        {            if(u==end)            {                int min=INF;                int loc;                for(int i=0; i<top; i++)                    if(min>edge[stack[i]].cap)                    {                        min=edge[stack[i]].cap;                        loc=i;                    }                for(int i=0; i<top; i++)                {                    edge[stack[i]].cap-=min;                    edge[stack[i]^1].cap+=min;                }                res+=min;                top=loc;                u=edge[stack[top]].from;            }            for(int i=cur[u]; i!=-1; cur[u]=i=edge[i].next)                if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to])                    break;            if(cur[u]!=-1)            {                stack[top++]=cur[u];                u=edge[cur[u]].to;            }            else            {                if(top==0)break;                dep[u]=-1;                u=edge[stack[--top]].from;            }        }    }    return res;}int score[20000],match[20000][2000],tot;void read(){    char s[1000];    gets(s);    n=0;    for(int i=0;s[i];i++)    {        int temp=0;        if( isdigit(s[i]) )        {            while(s[i] && isdigit(s[i]) )            {                temp=temp*10+s[i]-'0';                ++i;            }            --i;            score[++n]=temp;        }    }}bool build_and_check(int c){    init();    //tot = n*(n-1)/2;    int s = 0,t = n+1;    for(int i = 1; i<=n; i++)    {        addedge(i,t,score[i]);    }    for(int i = n+2; i<tot; i++)    {        addedge(s,i,1);    }    //int match= 1;    for(int i =1; i<=n; i++)    {        for(int j = i+1; j<=n; j++)        {            if(score[i] > score[j] && j >= n-c+1)            {                addedge(match[i][j],j,1);            }            else if(score[i] < score[j] && i >= n-c+1)            {                addedge(match[i][j],i,1);            }            else            {                addedge(match[i][j],i,1);                addedge(match[i][j],j,1);            }        }    }    int ans = dinic(s,t);    //printf("%d\n",ans);    return ans == (n*(n-1)/2);}int main(){//    ios::sync_with_stdio(0);//    cin.tie(0);    int ca = 0;    //char str[100];    scanf("%d%*c",&ca);    while(ca--)    {        n = 0;        //cout<<str<<endl;        read();        //cout<<n<<endl;        tot = n+2;        for(int i = 1; i<=n; i++)        {            for(int j =i+1; j<=n; j++)            {                match[i][j] = match[j][i] = tot++;            }        }        for(int i = n; i>=0; i--)        {            if(build_and_check(i))            {                printf("%d",i);                break;            }        }        printf("\n");    }    return 0;}

and thanks to kuangbin for his good dinic algorithm implementation

阅读全文
0 0
原创粉丝点击