标签:差分约束
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 6549 | Accepted: 3168 |
Description
Input
Output
Sample Input
4 2 1 1 3 10 2 4 20 2 3 3
Sample Output
27
解题思路:
1、构造差分约束系统:
A,B距离不超过D则B-A<=D,
A,B距离至少为D则A-B<=-D.
2、若有解则求1和N之间的最短路径:
例如:A-B<=D1 , B-C<=D2, A-C<=D3 不等式相加得:A-C<=min(D3,D1+D2)。而当A-B<=D时,我们建的边是B->A的,所以我们只要求出1到N的最短距离即可,如果没有最短距离,则输出-2.
#include <iostream> #include <cstdio> #include <queue> using namespace std; const int maxne = 1000000; const int maxnn = 1010; const int INF = 0x3f3f3f3f; struct edge{ int u , v , d; edge(int a = 0 , int b = 0 , int c = 0){ u = a , v = b , d = c; } }e[maxne]; int head[maxnn] , next[maxne] , cnt , dis[maxnn] , vis[maxnn] , vt[maxnn]; int N , ML , MD; void add(int u , int v , int d){ e[cnt] = edge(u , v , d); next[cnt] = head[u]; head[u] = cnt++; } void initial(){ for(int i = 0; i < maxnn; i++) head[i] = -1 , dis[i] = INF , vis[i] = 0 , vt[i] = 0; for(int i = 0; i < maxne; i++) next[i] = -1; cnt = 0; for(int i = 1; i < N; i++){ add(0 , i , 0); add(i+1 , i , 0); } add(0 , N , 0); dis[0] = 0; } void readcase(){ int u , v , d; while(ML--){ scanf("%d%d%d" , &u , &v , &d); add(u , v , d); } while(MD--){ scanf("%d%d%d" , &u , &v , &d); add(v , u , -1*d); } } bool SPFA(int start){ queue<int> q; q.push(start); vt[start]++; while(!q.empty()){ int u = q.front(); q.pop(); vis[u] = 0; int n = head[u]; if(vt[u] > N+1){ return false; } while(n != -1){ int v = e[n].v; if(dis[v] > dis[u]+e[n].d){ dis[v] = dis[u]+e[n].d; if(vis[v] == 0){ vt[v]++; q.push(v); vis[v] = 1; } } n = next[n]; } } return true; } void computing(){ if(!SPFA(0)){ printf("-1\n"); }else{ for(int i = 0; i < maxnn; i++) dis[i] = INF; dis[1] = 0; SPFA(1); if(dis[N] == INF){ printf("-2\n"); }else{ printf("%d\n" , dis[N]); } } } int main(){ while(scanf("%d%d%d" , &N , &ML , &MD) != EOF){ initial(); readcase(); computing(); } return 0; }
poj 3169 Layout(差分约束),布布扣,bubuko.com
标签:差分约束
原文地址:http://blog.csdn.net/u011836218/article/details/31419235