大意不再赘述。
思路:添加一个超级源点和电影数目连边,容量为需要的时间,然后将星期拆为7个点,如果有安排的话,就连边,容量为1,然后再从每个星期的7个点连一条边去汇点,容量为1,因为一天安排一个节目,最后判断压进去的流与总的天数之间的关系即可。
不知道为什么老是TLE,难道我的Dinic有问题??
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <string> using namespace std; const int MAXN = 1010; const int MAXM = 40010; const int INF = 0x3f3f3f3f; struct Edge { int v, f; int next; }edge[MAXM]; int first[MAXN], level[MAXN]; int map[MAXN][10]; int q[MAXN]; int cnt; int n, m; int MaxWeek, totDay; int s, t; void init() { cnt = 0; MaxWeek = 0; totDay = 0; memset(first, -1, sizeof(first)); } void read_graph(int u, int v, int f) { edge[cnt].v = v, edge[cnt].f = f; edge[cnt].next = first[u], first[u] = cnt++; edge[cnt].v = u, edge[cnt].f = 0; edge[cnt].next = first[v], first[v] = cnt++; } int bfs(int s, int t) { memset(level, 0, sizeof(level)); level[s] = 1; int front = 0, rear = 1; q[front] = s; while(front < rear) { int x = q[front++]; if(x == t) return 1; for(int e = first[x]; e != -1; e = edge[e].next) { int v = edge[e].v, f = edge[e].f; if(!level[v] && f) { level[v] = level[x] + 1; q[rear++] = v; } } } return 0; } int dfs(int u, int maxf, int t) { if(u == t) return maxf; int ret = 0; for(int e = first[u]; e != -1; e = edge[e].next) { int v = edge[e].v, f = edge[e].f; if(level[v] == level[u] + 1 && f) { int Min = min(maxf-ret, f); f = dfs(v, Min, t); edge[e].f -= f; edge[e^1].f += f; ret += f; if(ret == maxf) return ret; } } return ret; } int Dinic(int s, int t) { int ans = 0; while(bfs(s, t)) ans += dfs(s, INF, t); return ans; } void read_case() { init(); scanf("%d", &n); for(int i = 1; i <= n; i++) { for(int j = 1; j <= 9; j++) { scanf("%d", &map[i][j]); } MaxWeek = max(MaxWeek, map[i][9]); totDay += map[i][8]; } } void build() { s = 0, t = n + 7*MaxWeek + 1; for(int i = 1; i <= n; i++) { read_graph(s, i, map[i][8]); for(int j = 1; j <= map[i][9]; j++) { for(int k = 1; k <= 7; k++) if(map[i][k]) { read_graph(i, n+(j-1)*7+k, 1); } } } for(int i = 1; i <= MaxWeek; i++) { for(int j = 1; j <= 7; j++) { read_graph(n+(i-1)*7+j, t, 1); } } } void solve() { read_case(); build(); int ans = Dinic(s, t); if(ans >= totDay) printf("Yes\n"); else printf("No\n"); } int main() { int T; scanf("%d", &T); while(T--) { solve(); } return 0; }