sgu242:Student's Morning(网络流)

来源:互联网 发布:删除表多个字段sql 编辑:程序博客网 时间:2024/05/22 15:03

题目大意:
      n个学生和k个大学,每个学生有一个喜欢大学的列表,求出是否有方案可以满足每个学校去至少两个学生。

分析:
      网络流模板题…

AC code:

#include <cstdio>#include <cmath>#include <cstdlib>#include <cstring>#include <cctype>#include <algorithm>#include <string>#include <sstream>#include <iostream>#include <map>#include <set>#include <list>#include <stack>#include <queue>#include <vector>#define pb push_back#define inv(x) ((((x)-1)^1)+1)#define ONLINE_JUDGEtypedef long long LL;typedef double DB;typedef long double LD;using namespace std;const int MAXN = 209;const int MAXK = 209;const int MAX = MAXN+MAXK;const int MAXM = MAX*MAX;const int INF = 0x3f3f3f3f;int n, k;int s, t;struct Net{    int size;    int head[MAX];    int to[MAXM];    int f[MAXM];    int ne[MAXM];    Net() {size = 1;}    void add_edge(int u, int v, int flow)    {        to[size] = v, f[size] = flow, ne[size] = head[u], head[u] = size++;        to[size] = u, f[size] = 0, ne[size] = head[v], head[v] = size++;    }}G;int dis[MAX];vector<int> ans;bool spfa(int s, int t){    queue<int> q;    memset(dis, INF, sizeof(dis));    q.push(t), dis[t] = 0;    while(!q.empty())    {        int now = q.front();q.pop();        for(int i = G.head[now]; i; i = G.ne[i])        {            int to = G.to[i];            if(G.f[inv(i)] && dis[to] > dis[now]+1)            {                dis[to] = dis[now]+1;                q.push(to);             }        }    }    return dis[s] < INF;}int dfs(int now, int end, int flow){    if(now == end || !flow) return flow;    int ret = 0, tmp;    for(int i = G.head[now]; i; i = G.ne[i])    {        int to = G.to[i];        if(G.f[i] && dis[now]-1 == dis[to] && (tmp = dfs(to, end, min(flow, G.f[i]))))        {            G.f[i] -= tmp, G.f[inv(i)] += tmp;            flow -= tmp, ret += tmp;            if(!flow) break;            }    }    dis[now] = INF;    return ret;}int dinic(int s, int t){    int ret = 0;    while(spfa(s, t))        ret += dfs(s, t, INF);      return ret;}int main(){    #ifndef ONLINE_JUDGE    freopen("input.txt", "r", stdin);    freopen("output.txt", "w", stdout);    #endif    scanf("%d%d", &n, &k);    s = n+k+1, t = s+1;    for(int i = 1; i <= n; ++i)    {        int tmp, x;        scanf("%d", &tmp);        while(tmp--)        {            scanf("%d", &x);            G.add_edge(x, i+k, 1);        }    }    for(int i = 1; i <= k; ++i)        G.add_edge(s, i, 2);    for(int i = k+1; i <= n+k; ++i)        G.add_edge(i, t, 1);    if(dinic(s, t) != (k<<1)) puts("NO");    else    {        puts("YES");        for(int i = 1; i <= k; ++i)        {            for(int j = G.head[i]; j; j = G.ne[j])                if(G.to[j] >= k+1 && G.to[j] <= n+k && !G.f[j])                    ans.pb(G.to[j]-k);            printf("%d", ans.size());            sort(ans.begin(), ans.end());            for(int j = 0, sz = ans.size(); j < sz; ++j)                printf(" %d", ans[j]);            puts("");            ans.clear();        }    }    #ifndef ONLINE_JUDGE    fclose(stdin);    fclose(stdout);    #endif    return 0;}
0 0
原创粉丝点击