生活随笔
收集整理的這篇文章主要介紹了
【洛谷 P2763】 试题库问题(最大流)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接
6/23
這是網絡流23題里我第一個沒看題解自己寫出來一遍過的。。
這題應該是最簡單的模型了吧。
從源點向每個類型連一條流量為這個類型要的題數,再從每個類型向可以屬于這個類型的所有試題連一條流量為1的邊,最后從所有試題向匯點連一條流量為1的邊。
跑最大流就行。判斷邊有沒有流量。
// luogu-judger-enable-o2
#include <cstdio>
#include <queue>
#define INF 2147483647
using namespace std;
const int MAXN = 100010;
inline int read(){int s = 0, w = 1;char ch = getchar();while(ch < '0' || ch > '9'){ if(ch == '-') w = -1; ch = getchar(); }while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); }return s * w;
}
struct Edge{int next, to, from, rest;
}e[MAXN];
int s, t, num = 1, n, m, a;
int head[MAXN];
inline void Add(int from, int to, int flow){e[++num] = (Edge){ head[from], to, from, flow }; head[from] = num;e[++num] = (Edge){ head[to], from, to, 0 }; head[to] = num;
}
int flow[MAXN], pre[MAXN], dfn[MAXN], Time, now, sum;
queue <int> q;
int re(){pre[t] = 0; flow[s] = INF;q.push(s); dfn[s] = ++Time;while(q.size()){now = q.front(); q.pop();for(int i = head[now]; i; i = e[i].next)if(dfn[e[i].to] != Time && e[i].rest){dfn[e[i].to] = Time; q.push(e[i].to);flow[e[i].to] = min(flow[now], e[i].rest);pre[e[i].to] = i;}}return pre[t];
}
int dinic(){int ans = 0;while(re()){ans += flow[t];now = t;while(now != s){e[pre[now]].rest -= flow[t];e[pre[now] ^ 1].rest += flow[t];now = e[pre[now]].from;}}return ans;
}
int main(){s = 99999; t = 100000;n = read(); m = read();for(int i = 1; i <= n; ++i){sum += a = read();Add(s, i, a);}for(int i = 1; i <= m; ++i){a = read();for(int j = 1; j <= a; ++j)Add(read(), i + 1010, 1);Add(i + 1010, t, 1);}if(dinic() == sum)for(int i = 1; i <= n; ++i){printf("%d: ", i);for(int j = head[i]; j; j = e[j].next)if(e[j].to != s && !e[j].rest)printf("%d ", e[j].to - 1010);putchar('\n');}else printf("No Solution!\n");return 0;
}
轉載于:https://www.cnblogs.com/Qihoo360/p/10197894.html
總結
以上是生活随笔為你收集整理的【洛谷 P2763】 试题库问题(最大流)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。