Those are not the droids you're looking for Gym

来源:互联网 发布:域名被污染 编辑:程序博客网 时间:2024/05/28 03:01

题目根本粘贴不上,口述一波。

题目大意:有一天警察去一个酒吧去抓机器人,酒吧的老板说他这里只有两种人,没有机器人,这两种人的特点是,第一种人会在酒吧呆至少A个小时,另一种人会在网吧最多呆B个小时。现在给你酒吧门的进出记录,让酒吧老板自圆其说,如果不能自圆其说就说明老板是个骗子,否则就输出详细的人物进入与离开的时间。

首先想到二分匹配,大概做法就是建图+最大流。

方法:设超级起点s,超级终点f。s与每一个进入点连线,每一个出点与f连线,容量均为1.然后遍历所有入点与出点,如果可以链接那么就链接,容量也为1.

紧接着跑一个最大流就Ok,还有要记录一下节点。

AC代码如下:

#include<bits/stdc++.h>using namespace std;const int M=1e3+10;struct aa{    int u,v,r,next;} edge[1666666];int dis[M],pre[M],head[M],s,f,cnt,cnt1,cnt2,n,s1[M],s2[M],a,b;int mach[M];void add(int u,int v,int r){    edge[cnt].u=u;    edge[cnt].v=v;    edge[cnt].r=r;    edge[cnt].next=pre[u];    pre[u]=cnt++;    edge[cnt].u=v;    edge[cnt].v=u;    edge[cnt].r=0;    edge[cnt].next=pre[v];    pre[v]=cnt++;}bool bfs(){    memset(dis,-1,sizeof(dis));    queue<int>que;    dis[s]=0;    que.push(s);    while(!que.empty())    {        int u=que.front();        que.pop();        for(int i=pre[u]; i!=-1; i=edge[i].next)        {            int v=edge[i].v;            int r=edge[i].r;            if(dis[v]==-1&&r)            {                dis[v]=dis[u]+1;                que.push(v);            }        }    }    return dis[f]>=0;}int dfs(int now,int Min){    int T,flow=0;    if(now==f)        return Min;    for(int &i=head[now]; i!=-1; i=edge[i].next)    {        int v=edge[i].v;        int r=edge[i].r;        if(dis[v]==dis[now]+1&&r&&(T=dfs(v,min(Min-flow,r))))        {            edge[i].r-=T;            edge[i^1].r+=T;            mach[now]=v;            flow+=T;            if(flow==Min)                break;        }    }    return flow;}int MAX_flow(){    int sum=0;    int cont=1;    while(bfs())    {        for(int i=0; i<=n+1; i++)            head[i]=pre[i];        while(int temp=dfs(s,0x3f3f3f3f))            sum+=temp;    }    return sum;}int main(){    while(scanf("%d%d",&a,&b)!=EOF)    {        scanf("%d",&n);        cnt=0,cnt1=1;        cnt2=1;        memset(pre,-1,sizeof(pre));        memset(mach,0,sizeof(mach));        s=0,f=n+1;        for(int i=0; i<n; i++)        {            int t,p;            scanf("%d%d",&t,&p);            if(p==1)            {                s2[cnt2++]=t;            }            else            {                s1[cnt1++]=t;            }        }        for(int i=1; i<cnt1; i++)        {            add(s,i,1);            add(n/2+i,f,1);            for(int j=1; j<cnt2; j++)            {                if(s2[j]-s1[i]>=a||s2[j]-s1[i]<=b)                {                    add(i,n/2+j,1);                }            }        }        int ans=MAX_flow();        if(ans==n/2)        {            printf("No reason\n");            for(int i=1; i<=n/2; i++)            {                if(mach[i])                    printf("%d %d\n",s1[i],s2[mach[i]-n/2]);            }        }        else        {            printf("Liar\n");        }    }}


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