hdu 4309 状压+最大流
来源:互联网 发布:dpp软件 编辑:程序博客网 时间:2024/06/05 22:34
传送门
题目大意:有n个城市,每个城市有一个人数,城市与城市之间有三种通道(均为单向):隧道,公路和桥。隧道和公路都可以通过无限制的人,并且隧道可以避难ai人。桥没有修理的时候只能通过一个人次,修理之后就和公路没有差别了,修理有费用。特别注意桥不超过12条。求通过最大人数,最少修理话费。
最多只有12个。。。。直接枚举可能就过了--4000+种可能情况而已。每次输入的时候记录有多少个桥需要修 cnt++ 状压枚举的时候一定是枚举修桥之后的情况
枚举方法(状压 1<<cnt
每个状态求一次流量,然后更新答案。
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <algorithm>using namespace std;const int maxn = 60007;const int maxm = 65000;const int oo = 99999999;int idx;int cur[maxn], pre[maxn];int dis[maxn], gap[maxn];int aug[maxn], head[maxn];struct Node{ int u, v, w; int next;}edge[maxm];void addEdge(int u, int v, int w){ edge[idx].u = u; edge[idx].v = v; edge[idx].w = w; edge[idx].next = head[u]; head[u] = idx++; edge[idx].u = v; edge[idx].v = u; edge[idx].w = 0; edge[idx].next = head[v]; head[v] = idx++;}int SAP(int s, int e, int n){ int max_flow = 0, v, u = s; int id, mindis; aug[s] = oo; pre[s] = -1; memset(dis, 0, sizeof(dis)); memset(gap, 0, sizeof(gap)); gap[0] = n; // 我觉得这一句要不要都行,因为dis[e]始终为0 for (int i = 0; i <= n; ++i) { // 初始化当前弧为第一条弧 cur[i] = head[i]; } while (dis[s] < n) { bool flag = false; if (u == e) { max_flow += aug[e]; for (v = pre[e]; v != -1; v = pre[v]) // 路径回溯更新残留网络 { id = cur[v]; edge[id].w -= aug[e]; edge[id^1].w += aug[e]; aug[v] -= aug[e]; // 修改可增广量,以后会用到 if (edge[id].w == 0) u = v; // 不回退到源点,仅回退到容量为0的弧的弧尾 } } for (id = cur[u]; id != -1; id = edge[id].next) { // 从当前弧开始查找允许弧 v = edge[id].v; if (edge[id].w > 0 && dis[u] == dis[v] + 1) // 找到允许弧 { flag = true; pre[v] = u; cur[u] = id; aug[v] = min(aug[u], edge[id].w); u = v; break; } } if (flag == false) { if (--gap[dis[u]] == 0) break; /* gap优化,层次树出现断层则结束算法 */ mindis = n; cur[u] = head[u]; for (id = head[u]; id != -1; id = edge[id].next) { v = edge[id].v; if (edge[id].w > 0 && dis[v] < mindis) { mindis = dis[v]; cur[u] = id; // 修改标号的同时修改当前弧 } } dis[u] = mindis + 1; gap[dis[u]]++; if (u != s) u = pre[u]; // 回溯继续寻找允许弧 } } return max_flow;}int val[1010];struct node{ int u,v,w,p;}Q[1010];//int map[300][300];int main(){ int t, n, m, pi, si, ei; int Max, sum, source, sink, vn; //scanf("%d", &t); t=1; for (int cas = 1; cas <= t; ++cas) { //scanf("%d%d",&n,&m); while(scanf("%d%d",&n,&m)!=EOF) { int flag=0; for(int i=1;i<=n;i++) scanf("%d",&val[i]); // getchar(); int cnt=0; for(int i=1;i<=m;i++) { scanf("%d%d%d%d",&Q[i].u,&Q[i].v,&Q[i].w,&Q[i].p); if(Q[i].p>0) cnt++; if(Q[i].p<0&&Q[i].w!=0) { flag=1; // cout<<"*****"<<endl; } // cout<<Q[i].p<<" "; } if(!flag) { puts("Poor Heaven Empire"); continue; } int mm=(1<<cnt); int maxnum=-oo,mincost=0; for(int k=0;k<mm;k++) { idx = 0; source = 0;sink = n + 1; vn = sink + 1; memset(head, -1, sizeof(head)); sum = 0; Max = 0; /* for (int i = 1; i <= n; ++i) { scanf("%d %d %d", &pi, &si, &ei); sum += pi; Max = max(Max, ei); addEdge(source, i, pi); for (int j = si; j <= ei; ++j) { addEdge(i, n + j, 1); } } */ //cout<<endl; int j=0,cost=0; for(int i=1;i<=n;i++) addEdge(0,i,val[i]); for(int i=1;i<=m;i++) { //cout<<Q[i].u<<" "<<Q[i].v<<" "<<Q[i].w<<" "<<Q[i].p<<endl; if(Q[i].p<0) { addEdge(Q[i].u,Q[i].v,oo); addEdge(Q[i].u,sink,Q[i].w); } else if(Q[i].p==0) addEdge(Q[i].u,Q[i].v,oo); else { //cout<<Q[i].p<<" ****"<<endl; if(k&(1<<j)) { addEdge(Q[i].u,Q[i].v,oo); cost+=Q[i].w; // cout<<cost<<endl; } else addEdge(Q[i].u,Q[i].v,1); j++; } } int ans=SAP(0,sink,vn); if(ans>maxnum||(ans==maxnum&&cost<mincost)) { maxnum=ans; mincost=cost; } } if(maxnum>0) printf("%d %d\n",maxnum,mincost); else printf("Poor Heaven Empire\n"); /*for (int i = 1; i <= Max; ++i) { addEdge(n + i, sink, m); } if (SAP(source, sink, vn) == sum) printf("Case %d: Yes\n\n", cas); else printf("Case %d: No\n\n", cas); */ } } return 0;}
阅读全文
0 0
- hdu 4309 状压+最大流
- hdu 4309 最大流 + DFS
- hdu 4309 状压枚举+最大流
- hdu 4309(最大流+枚举状态)
- HDU 3605 Escape 最大流,状压
- HDU-3605-Escape(最大流+状压)
- hdu 2883(最大流)
- 【最大流】HDU 3572
- hdu 2883 最大流
- hdu 3572最大流
- hdu 3605 最大流
- HDU 1733 最大流
- hdu 3549 最大流
- hdu 2732 最大流
- hdu 3605 (最大流)
- hdu 2883 (最大流)
- hdu 3081 (最大流)
- hdu 3549 最大流
- linux之入门---使用帮助命令解决问题
- JQuery常用方法
- tab切换功能——vue
- jQuery事件及文档处理
- [UVa11400]照明系统设计
- hdu 4309 状压+最大流
- 图片
- 本地网页样式上传服务器后发生变化解决办法
- android NDk编程
- HTTP网页错误代码大全
- 子节点生成Tab的非空判断与重复判断
- 用Python做深度学习(一)
- 日常学习2017..18
- QT实现竖直方向的窗口布局(使用QLayout类)