标签:
Description
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int MAXN = 520;
const int MAXM = 100000;
const int INF = 0x3f3f3f3f;
struct Edge
{
int from, to, cap, next, oricap;
};
Edge edge[MAXM];
int head[MAXN];
int stu[405][405];
int level[MAXN];
int src, des, cnt;
void addedge( int from, int to, int cap )
{
edge[cnt].from = from;
edge[cnt].to = to;
edge[cnt].cap = cap;
edge[cnt].oricap = cap;
edge[cnt].next = head[from];
head[from] = cnt++;
swap( from, to );
edge[cnt].from = from;
edge[cnt].to = to;
edge[cnt].cap = 0;
edge[cnt].oricap = 0;
edge[cnt].next = head[from];
head[from] = cnt++;
}
int bfs( )
{
memset( level, -1, sizeof level );
queue<int> q;
while (!q.empty( ))
q.pop( );
level[src] = 0;
q.push( src );
while (!q.empty( ))
{
int u = q.front( );
q.pop( );
for (int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if (edge[i].cap > 0 && level[v] == -1)
{
level[v] = level[u] + 1;
q.push( v );
}
}
}
return level[des] != -1;
}
int dfs( int u, int f )
{
if (u == des) return f;
int tem;
for (int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if (edge[i].cap > 0 && level[v] == level[u] + 1)
{
tem = dfs( v, min( f, edge[i].cap ) );
if (tem > 0)
{
edge[i].cap -= tem;
edge[i ^ 1].cap += tem;
return tem;
}
}
}
level[u] = -1;
return 0;
}
int Dinic( )
{
int ans = 0, tem;
while (bfs( ))
{
while ((tem = dfs( src, INF )) > 0)
{
ans += tem;
}
}
return ans;
}
int main( )
{
int n, m;
src = 0; des = 510;
string str;
while (cin >> n >> m)
{
memset( head, -1, sizeof head );
cnt = 0;
for (int i = 1; i <= n; i++)
{
addedge( src, i, 1 );
int unum;
cin >> unum;
for (int j = 1; j <= unum; j++)
{
int u;
cin >> u;
addedge( i, u + 200, 1 );
}
}
for (int i = 1; i <= m; i++)
{
addedge( i + 200, des, 2 );
stu[i + 200][0] = 0;
}
if (Dinic( ) < m * 2)
{
cout << "NO" << endl;
continue;
}
for (int i = 1; i <= n; i++)
{
for (int j = head[i]; j != -1; j = edge[j].next)
{
if (edge[j].to != src&&edge[j].oricap>edge[j].cap)
{
stu[edge[j].to][++stu[edge[j].to][0]] = i;
}
}
}
cout << "YES" << endl;
for (int i = 1; i <= m; i++)
{
cout << stu[i + 200][0] << " ";
for (int j = 1; j < stu[i + 200][0]; j++)
{
cout << stu[i + 200][j] << " ";
}
cout << stu[i + 200][stu[i + 200][0]] << endl;
}
}
return 0;
}解题报告 之 SGU242 Student's Morning
标签:
原文地址:http://blog.csdn.net/maxichu/article/details/45220453