题意:进门和出门的人,如果有一组有全部的人都符合其在酒巴的时间>=a或者<=b,则为No reason,且输出入门出门的时间,否则为Liar。
这题太晕了……尼玛!把边的指向指错了,得先入门指向出门的才行,刚开始就这样一直WA,所以……
感觉这题收获太大了,以前没有全部理解二分图的后果耶,现在终于理解了。
二分图这题是单向边的,如果改为无向图的话,就是匹配*2了;
然后还有一点就是pre数组的使用,以前没有全部理解,哈哈,原来可以用pre数组用来输出当前点的前身结点,这以前怎么就不会呢,可能是以前没有遇到过吧!!!虽然以前知道这个是前向数组,即前向星,但是还没用来过输出呢,这题还是练得很好的……把自己的缺点都给暴露无疑了……
#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <list>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define PI acos(-1.0)
#define mem(a,b) memset(a,b,sizeof(a))
#define sca(a) scanf("%d",&a)
#define pri(a) printf("%d\n",a)
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define MM 1000005
#define MN 1010
#define INF 55566677
#define eps 1e-7
using namespace std;
typedef long long ll;
int cnt=1,tem=1,s[MN],z[MN],vis[MN],pre[MN],Map[MN][MN];
int dfs(int u)
{
for(int v=1;v<cnt;v++)
if(!vis[v]&&Map[u][v])
{
vis[v]=1;
if(!pre[v]||dfs(pre[v]))
{
pre[v]=u;
return 1;
}
}
return 0;
}
int solve()
{
int ans=0,i;
for(i=1;i<cnt;i++)
{
mem(vis,0);
ans+=dfs(i);
}
return ans;
}
int main()
{
int a,b,u,bb,n,i,j;
scanf("%d%d%d",&a,&b,&n);
for(i=0;i<n;i++)
{
scanf("%d%d",&u,&bb);
if(bb) s[cnt++]=u;
else z[tem++]=u;
}
if(cnt!=tem||n&1) {puts("Liar");return 0;}
for(i=1;i<cnt;i++)
for(j=1;j<cnt;j++)
{
int f=s[j]-z[i]; //原来是人先进去然后才出门
//刚开始写s[i]-z[j]就错了,wa了多发改了才过,过!!!
if(f>=0&&(f>=a||f<=b)) Map[i][j]=1;
}
if(solve()==cnt-1)
{
puts("No reason");
for(i=1;i<cnt;i++)
printf("%d %d\n",z[pre[i]],s[i]);
}
else puts("Liar");
return 0;
}