POJ3169 Layout 差分约束系统[三星]
2015-11-01 15:28
337 查看
题目链接:POJ
CodeVs
由于是英文题目就不再复制题面了~
昨天看CV月赛的题看到这个题,因为Std有个地方看不懂所以自己再做了一下。
首先本题仔细读题后发现求最大值,于是就跑最短路:
然后再仔细读题会发现3个约束条件:
①:两个妹子不和,b-a >= c的情况,将它转化为最短路形式的约束条件就是:a<=b-c(这里我用的我总结的方法,链接:QAQAQAQ)这种情况下是b向a建一条权值为-c的边
②:两个妹子是百合,b-a<=c的情况,将它转换变成了:b<=a+c,即a向b建一条权值为c的边。
③:两个位置可以重合,但我们按从左向右的顺序来的话就是a <= b,即b向a建一条权值为0的边。
这样约束条件都列举了出来,之后再建边就行了,-1的情况是无解的情况,即存在负环,-2的情况是无法约束1到n距离的情况,即再约束系统中没有从1到达n的路径,如果都不是上面两种情况,就输出答案。
网上有篇std是将约束条件①反过来读,就是先读b再读a然后b->a建边……和我的想法其实是一致的QAQ
完整代码:
CodeVs
由于是英文题目就不再复制题面了~
昨天看CV月赛的题看到这个题,因为Std有个地方看不懂所以自己再做了一下。
首先本题仔细读题后发现求最大值,于是就跑最短路:
然后再仔细读题会发现3个约束条件:
①:两个妹子不和,b-a >= c的情况,将它转化为最短路形式的约束条件就是:a<=b-c(这里我用的我总结的方法,链接:QAQAQAQ)这种情况下是b向a建一条权值为-c的边
②:两个妹子是百合,b-a<=c的情况,将它转换变成了:b<=a+c,即a向b建一条权值为c的边。
③:两个位置可以重合,但我们按从左向右的顺序来的话就是a <= b,即b向a建一条权值为0的边。
这样约束条件都列举了出来,之后再建边就行了,-1的情况是无解的情况,即存在负环,-2的情况是无法约束1到n距离的情况,即再约束系统中没有从1到达n的路径,如果都不是上面两种情况,就输出答案。
网上有篇std是将约束条件①反过来读,就是先读b再读a然后b->a建边……和我的想法其实是一致的QAQ
完整代码:
[code]#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<stack> using namespace std; typedef long long ll; const int size = 100010; const int INF = 1077952576; struct Edge{int to,dist;}edges[size]; int head[size],next[size],tot; void build(int f,int t,int d) { edges[++tot].to = t; edges[tot].dist = d; next[tot] = head[f]; head[f] = tot; } int n,m,k; int dist[size],cishu[size]; bool vis[size]; deque <int> q; bool spfa() { memset(dist,64,sizeof(dist)); q.push_back(1); vis[1] = 1; dist[1] = 0; while(!q.empty()) { int f = q.front(); q.pop_front(); vis[f] = 0; for(int i = head[f];i;i = next[i]) { int v = edges[i].to; if(dist[v] > dist[f] + edges[i].dist) { dist[v] = dist[f] + edges[i].dist; if(!vis[v]) { cishu[v] ++; if(cishu[v] > n) return true; vis[v] = 1; if(!q.empty() && dist[v] < dist[q.front()]) q.push_front(v); else q.push_back(v); } } } } return false; } int main() { scanf("%d%d%d",&n,&m,&k); for(int i = 1;i <= m;i ++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); build(a,b,c); } for(int i = 1;i <= k;i ++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); build(b,a,-c); } for(int i = 1;i < n;i ++) build(i+1,i,0); if(spfa()) puts("-1"); else if(dist == INF) puts("-2"); else printf("%d",dist ); return 0; }
相关文章推荐
- linux资源数和线程数限制修改方法
- Redis快速入门
- 【poj3169】Layout 差分约束
- 标准库std::string写时拷贝
- PHP+Mysql+AJAX登录验证
- tcp/dccp: lockless listener
- ios学习之苹果官方文档的学习(EKEventEditViewController)
- CSS文本
- 近来学习状态的总结!
- MyBatis入门(五)---延时加载、缓存
- (NO.00002)iOS游戏精灵战争雏形(十)
- 2015长春赛 Almost Sorted Array
- 数据库触发器DB2和SqlServer有哪些区别
- OpenVAS漏洞扫描
- (NO.00002)iOS游戏精灵战争雏形(十)
- (NO.00002)iOS游戏精灵战争雏形(十)
- 20135337——信息安全设计基础第七周复习笔记
- android 69 SQLite数据库
- Android中Math取整的三个方法
- 织梦DedeCms如何批量修改文章发布时间