扔硬币
Solve the Equation
视频监控
MFA Algorithm
Circle VS Triangle
电脑密码
The Key Locker of Cell Phone
Number Maze
修路问题
浪漫自习
最大流EK 可以过
取一个源点0 建一条边 0-1 容量为m(情侣的对数)
如果最大流等于m 就YES
此外我建图比较麻烦
对于每一条无向边 我拆成2条有向 每条有向边还有一条反向边 4条 初学
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAX = 55;
int n,m;
struct edge
{
int u;
int v;
int flow;
int cap;
int next;
}e[10000];
int cap[MAX][MAX];
int a[MAX];
int first[MAX];
int p[MAX];
int edgenum;
int f,c;
int s,t;
void add(int u,int v,int cap)
{
e[edgenum].u = u;
e[edgenum].v = v;
e[edgenum].flow = 0;
e[edgenum].cap = cap;
e[edgenum].next = first[u];
first[u] = edgenum++;
e[edgenum].u = v;
e[edgenum].v = u;
e[edgenum].flow = 0;
e[edgenum].cap = 0;
e[edgenum].next = first[v];
first[v] = edgenum++;
}
void EK()
{
queue <int> q;
f = 0;
while(1)
{
memset(a,0,sizeof(a));
memset(p,-1,sizeof(p));
a[0] = 999999999;
q.push(0);
while(!q.empty())
{
int u = q.front();
q.pop();
for(int k = first[u]; k != -1; k = e[k].next)
{
int v = e[k].v;
if(!a[v] && e[k].cap > e[k].flow)
{
p[v] = k;
q.push(v);
a[v] = min(a[u],e[k].cap - e[k].flow);
}
}
}
if(a[t] == 0)
break;
for(int k = p[t]; k != -1; k = p[e[k].u])
{
e[k].flow += a[t];
e[k^1].flow -= a[t];
}
f += a[t];
}
}
int main()
{
int i,j,k;
while(scanf("%d %d",&m,&n),n||m)
{
edgenum = 0;
s = 0;
t = 2;
memset(first,-1,sizeof(first));
memset(cap,0,sizeof(cap));
add(0,1,m);
for(i = 1; i <= n; i++)
{
scanf("%d",&k);
while(k--)
{
scanf("%d",&j);
cap[i][j] = cap[j][i] = 1;
//add(i,j,1);
//add(j,i,1);
}
}
for(i = 1;i <= n; i++)
for(j = i+1; j <= n; j++)
if(cap[i][j])
{
add(i,j,1);
add(j,i,1);
}
EK();
if(f == m)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
自动门控制