POJ2983 查分约束系统
生活随笔
收集整理的這篇文章主要介紹了
POJ2983 查分约束系统
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ? ?給你n個點,然后給你兩種情況,P a b c,表明a在b的北邊c那么遠,V a b 表明a在b的北邊(距離最少是1),問你這些條件是否沖突。
思路:
? ? ? 一開始想用帶權并查集,先處理P在處理V,想想感覺不對,還是查分約束吧,查分約束處理這個題時間和建圖都簡單,首先查分約束是根據最短路(或最長路)的不等式關系建圖的,給你一個圖,跑完最短路對于邊<a ,b> 會有dis[b] <= dis[a] + map[a][b];
則 dis[b] - dis[a] <= map[a][b](或者也可以dis[a] - dis[b] >= map[a][b],只不過這樣要跑最長路),對于這個題目,
V a b ? ?: add(a ,b ,1).
P a b c ?: add(a ,b ,c) ,add(b ,a ,-c).
跑一遍最長路,或者
V a b ? ?: add(a ,b ,-1).
P a b c ?: add(a ,b ,-c),add(b ,a ,c).
跑一遍最短路。
??
? ? ??
? ? ? ?給你n個點,然后給你兩種情況,P a b c,表明a在b的北邊c那么遠,V a b 表明a在b的北邊(距離最少是1),問你這些條件是否沖突。
思路:
? ? ? 一開始想用帶權并查集,先處理P在處理V,想想感覺不對,還是查分約束吧,查分約束處理這個題時間和建圖都簡單,首先查分約束是根據最短路(或最長路)的不等式關系建圖的,給你一個圖,跑完最短路對于邊<a ,b> 會有dis[b] <= dis[a] + map[a][b];
則 dis[b] - dis[a] <= map[a][b](或者也可以dis[a] - dis[b] >= map[a][b],只不過這樣要跑最長路),對于這個題目,
V a b ? ?: add(a ,b ,1).
P a b c ?: add(a ,b ,c) ,add(b ,a ,-c).
跑一遍最長路,或者
V a b ? ?: add(a ,b ,-1).
P a b c ?: add(a ,b ,-c),add(b ,a ,c).
跑一遍最短路。
提醒一點就是別忘記建立超級原點s,s到每個點的距離都是0,這樣是為了防止整個圖不是一個聯通快。
#include<stdio.h> #include<string.h> #include<queue>#define N_node 2000 + 10 #define N_edge 500000 + 200 #define INF 1000000000using namespace std;typedef struct {int to ,next ,cost; }STAR;STAR E[N_edge]; int list[N_node] ,tot; int in[N_node]; int s_x[N_node];void add(int a ,int b ,int c) {E[++tot].to = b;E[tot].cost = c;E[tot].next = list[a];list[a] = tot; }bool spfa(int s ,int n) {int mark[N_node] = {0};memset(in ,0 ,sizeof(in));for(int i = 0 ;i <= n ;i ++)s_x[i] = -INF;s_x[s] = 0;mark[s] = 1;in[s] ++;queue<int>q;q.push(s);while(!q.empty()){int xin ,tou;tou = q.front();q.pop();mark[tou] = 0;for(int k = list[tou] ;k ;k = E[k].next){xin = E[k].to;if(s_x[xin] < s_x[tou] + E[k].cost){s_x[xin] = s_x[tou] + E[k].cost;//printf("%d %d***\n" ,tou ,xin);if(!mark[xin]){mark[xin] = 1;if(++in[xin] > n) return 0;q.push(xin);}}}} return 1; }int main () {int i ,n ,m ,a ,b ,c;char str[10];while(~scanf("%d %d" ,&n ,&m)){memset(list ,0 ,sizeof(list));tot = 1;for(i = 1 ;i <= m ;i ++){scanf("%s" ,str);if(str[0] == 'P'){scanf("%d %d %d" ,&a ,&b ,&c);add(a ,b ,c);add(b ,a ,-c);}else{scanf("%d %d" ,&a ,&b);add(a ,b ,1);}}for(i = 1 ;i <= n ;i ++)add(0 ,i ,0);if(spfa(0 ,n)) printf("Reliable\n");else printf("Unreliable\n");}return 0; }
??
? ? ??
總結
以上是生活随笔為你收集整理的POJ2983 查分约束系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ2594 最小路径覆盖
- 下一篇: POJ 1961 KMP(当前重复次数)