NWERC 2012 A - Admiral【最小费用最大流】
2014-05-24 17:04
337 查看
题意:
有n个岛屿 起点1 终点 n
现在两个人同时从起点出发向终点前进
两个人的路径不能有交集(一个人走过的路另一个人不能再走了)
问两个人的最小总花费
分析:
刚开始的的时候以为是最短路和次短路的和就行了 (太天真了)
快要结束的时候突然间发现这不就是传说中的最小费用最大流问题吗
可惜时间不够
思路是这样的:因为两个人来走,所以输入和输出的流量为1 费用为0
而连接的两点流量为1花费为权值
建图即可
结束之后敲完了代码,测试数据通过
不过没有地方提交
在程的帮助下重启pc^2完成了提交,
可是
结果却是wrong
很苦恼啊
于是各种修改啊
还是wrong
最后在网上搜了一下题解
我终于知道wrong的地方了
就跟牛选食物跟饮料那个题一样的 ,如果一头牛同时喜欢两种食物和两种饮料的话,结果就是不对的
这个题类似
修改方法便是拆点
代码如下:
View Code
有n个岛屿 起点1 终点 n
现在两个人同时从起点出发向终点前进
两个人的路径不能有交集(一个人走过的路另一个人不能再走了)
问两个人的最小总花费
分析:
刚开始的的时候以为是最短路和次短路的和就行了 (太天真了)
快要结束的时候突然间发现这不就是传说中的最小费用最大流问题吗
可惜时间不够
思路是这样的:因为两个人来走,所以输入和输出的流量为1 费用为0
而连接的两点流量为1花费为权值
建图即可
结束之后敲完了代码,测试数据通过
不过没有地方提交
在程的帮助下重启pc^2完成了提交,
可是
结果却是wrong
很苦恼啊
于是各种修改啊
还是wrong
最后在网上搜了一下题解
我终于知道wrong的地方了
就跟牛选食物跟饮料那个题一样的 ,如果一头牛同时喜欢两种食物和两种饮料的话,结果就是不对的
这个题类似
修改方法便是拆点
代码如下:
//已ac #include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue> using namespace std; const int maxn = 10005; const int INF = 1000000000; struct Edge { int from, to, cap, flow, cost;//起点 终点 容量 花费 }; struct MCMF { int n, m, s, t; vector<Edge> edges; vector<int> G[maxn]; int inq[maxn]; int d[maxn]; int p[maxn]; int a[maxn]; void init(int n) {//初始化的是所有的点数 this -> n = n; for(int i = 0; i < n; i++) G[i].clear(); edges.clear(); } void AddEdge(int from, int to, int cap, int cost) { edges.push_back((Edge) { from, to, cap, 0, cost } ); edges.push_back((Edge) { to, from, 0, 0, -cost } ); m = edges.size(); G[from].push_back(m - 2); G[to].push_back(m - 1); } bool BellmanFord(int s, int t, int &flow, int &cost) { for(int i = 0; i < n; i++) d[i] = INF; memset(inq, 0, sizeof(inq) ); d[s] = 0; inq[s] = 1; p[s] = 0; a[s] = INF; queue<int> Q; Q.push(s); while(!Q.empty()) { int u = Q.front(); Q.pop(); inq[u] = 0; for(int i = 0; i < G[u].size(); i++) { Edge &e = edges[G[u][i]]; if(e.cap > e.flow && d[e.to] > d[u] + e.cost) { d[e.to] = d[u] + e.cost; p[e.to] = G[u][i]; a[e.to] = min(a[u], e.cap - e.flow); if(!inq[e.to]) { Q.push(e.to); inq[e.to] = 1; } } } } if(d[t] == INF) return false; flow += a[t]; cost += d[t] * a[t]; int u = t; while(u != s) { edges[p[u]].flow += a[t]; edges[p[u] ^ 1].flow -= a[t]; u = edges[p[u]].from; } return true; } int MinCost(int s, int t) {//起点和终点 // this -> s = s; this -> t = t; int flow = 0, cost = 0; while(BellmanFord(s, t, flow, cost)){}; return cost; } }; MCMF g; int main() { int n, m; int a, b, c; freopen("a.txt","r",stdin); while(EOF != scanf("%d %d",&n, &m)) { g.init(n * 2 + 1); g.AddEdge(1, 1 + n, 2, 0); g.AddEdge(n, n + n, 2, 0); for(int i = 2; i <= n - 1; i++) { g.AddEdge(i, i + n, 1, 0); } for(int i = 0; i < m; i ++) { scanf("%d %d %d",&a, &b, &c); g.AddEdge(a + n, b, 1, c); } printf("%d\n",g.MinCost(1, n + n)); } return 0; }
View Code
相关文章推荐
- NWERC 2012 Problem A Admiral
- uva1658 Admiral 最小费用最大流
- NWERC 2012 Problem J Joint Venture
- hdu 4411 2012杭州赛区网络赛 最小费用最大流 ***
- 2012-2013 Northwestern European Regional Contest (NWERC 2012)【solved:6 / 11】
- NWERC 2012 练习赛题解
- NWERC 2012 Problem E Edge Case
- UVA1658 - Admiral(最小费用最大流+拆点)
- [luoguP3159] [CQOI2012]交换棋子(最小费用最大流)
- NWERC 2012 Problem I Idol
- uva 1658 Admiral 【 最小费用最大流 】
- Admiral UVA - 1658 最小费用最大流
- UVA1658 Admiral 拆点法解决结点容量(路径不能有公共点,容量为1的时候) 最小费用最大流
- 最小费用最大流--uva1658 Admiral
- [BZOJ2879][Noi2012]美食节(最小费用最大流动态加边)
- NWERC 2012 Foul Play 构造 (uvaLive 6271 )
- UVa 1658 Admiral (最小费用最大流、拆点法)
- UVA - 1658 Admiral (最小费用最大流)
- H Hip To Be Square Day5——NWERC2012
- UVA 1658 Admiral 最小费用最大流