poj-1698-Alice's Chance
2016-05-02 09:21
309 查看
这道题主要难点是构图,想了半天也想不懂怎么构图,后来在网上找了一下别人的题解
构图:把每个电影需要的星期数都拆开,变成一条线的权值设为1,这样每个星期中的某一天只能被一部电影占据,源点直接连接到电影,权值为需要的天数,之后将日期和汇点相连,比如有一部电影需要4周,就需要有4*7=28个点和汇点相连!
把图画出来就直接用dinic算法就行了
Dinic算法的原理与构造
构图:把每个电影需要的星期数都拆开,变成一条线的权值设为1,这样每个星期中的某一天只能被一部电影占据,源点直接连接到电影,权值为需要的天数,之后将日期和汇点相连,比如有一部电影需要4周,就需要有4*7=28个点和汇点相连!
把图画出来就直接用dinic算法就行了
Dinic算法的原理与构造
#include <iostream> #include <cstdio> #include <cstring> #define ll long long #define N 400 const int INF = 0x3f3f3f3f; using namespace std; struct Edge{ int v, f; int next; }edge[N*N]; int n, first , cnt, q , F[22][8], level ; void Init(){ cnt = 0; memset(first, -1, sizeof(first)); } void read(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++; } bool bfs(int s, int t){ memset(level, 0, sizeof(level)); level[s] = 1; int rear = 0, front = 0; q[front++] = s; while(rear < front){ int x = q[rear++]; if (x == t) return true; for (int e = first[x]; e != -1; e = edge[e].next){ int v = edge[e].v; int f = edge[e].f; if (!level[v] && f){ level[v] = level[x]+1; q[front++] = v; } } } return false; } int Dinic(int s, int t){ int ans = 0; while(bfs(s, t)){ int e, x, y, back, iter = 1; while(iter){ x = (iter==1)?s:edge[q[iter-1]].v; if (x == t){ int minCap = INF; for (int i = 1; i < iter; i++){ e = q[i]; if (edge[e].f < minCap){ minCap = edge[e].f; back = i; } } for (int i = 1; i < iter; i++){ e = q[i]; edge[e].f -= minCap; edge[e^1].f += minCap; } ans += minCap; iter = back; }else{ for (e = first[x]; e != -1; e = edge[e].next){ y = edge[e].v; if (edge[e].f && level[y] == level[x]+1){ break; } } if (e != -1){ q[iter++] = e; } else{ level[x] = -1; iter--; } } } } return ans; } int main(){ #ifndef ONLINE_JUDGE freopen("1.txt", "r", stdin); #endif int i, j, k, T, d, w, sum, flag; scanf("%d", &T); while(T--){ sum = 0; flag = 0; Init(); scanf("%d", &n); for (i = 1; i <= n; i++){ for (j = 1; j <= 7; j++){ scanf("%d", &F[i][j]); } scanf("%d%d", &d, &w); read(0, i, d); sum += d; flag = max(flag, w); for (k = 0; k < w; k++){ for (j = 1; j <= 7; j++){ if (F[i][j]){ read(i, 7*k+j+n, 1); } } } } int tmp = n+7*flag+1; for (i = 0; i < flag; i++){ for (j = 1; j <= 7; j++){ read(7*i+n+j, tmp, 1); } } int ans = Dinic(0, tmp); if (sum == ans){ puts("Yes"); }else{ puts("No"); } } return 0; }
相关文章推荐
- 清理Kylin的中间存储数据(HDFS & HBase Tables)
- 备份Kylin的元数据
- 民以食为天 食以安为先
- 如何快速精通C语言
- C#OOP之十五 String类&StringBuilder类
- C#OOP之十五 String类&StringBuilder类
- 鸟哥的Linux私房菜-Read_02
- Java内存分配全面浅析
- C#OOP之十五 String类&StringBuilder类
- Cannot read property 'getElementsByTagName' of null
- poj 2406 Power Strings(KMP)
- NYOJ 47 过河问题(贪心)
- 基本数据与String以及包装类的转换
- NYOJ 矩形嵌套
- PHP pcntl_fork不能在web服务器中使用的变通方法
- Hibernate之性能优化
- debian + xfce解决不能自动挂载U盘问题
- XMG tableView左滑动多操作
- C++将矩阵存到.txt文件, 使用 FILE 或 ofstream
- 作为产品经理在设计产品过程中你需要使用哪些文档?