POJ2983 查分约束系统
生活随笔
收集整理的這篇文章主要介紹了
POJ2983 查分约束系统
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題意:
? ? ? ?給你n個(gè)點(diǎn),然后給你兩種情況,P a b c,表明a在b的北邊c那么遠(yuǎn),V a b 表明a在b的北邊(距離最少是1),問(wèn)你這些條件是否沖突。
思路:
? ? ? 一開(kāi)始想用帶權(quán)并查集,先處理P在處理V,想想感覺(jué)不對(duì),還是查分約束吧,查分約束處理這個(gè)題時(shí)間和建圖都簡(jiǎn)單,首先查分約束是根據(jù)最短路(或最長(zhǎng)路)的不等式關(guān)系建圖的,給你一個(gè)圖,跑完最短路對(duì)于邊<a ,b> 會(huì)有dis[b] <= dis[a] + map[a][b];
則 dis[b] - dis[a] <= map[a][b](或者也可以dis[a] - dis[b] >= map[a][b],只不過(guò)這樣要跑最長(zhǎng)路),對(duì)于這個(gè)題目,
V a b ? ?: add(a ,b ,1).
P a b c ?: add(a ,b ,c) ,add(b ,a ,-c).
跑一遍最長(zhǎng)路,或者
V a b ? ?: add(a ,b ,-1).
P a b c ?: add(a ,b ,-c),add(b ,a ,c).
跑一遍最短路。
??
? ? ??
? ? ? ?給你n個(gè)點(diǎn),然后給你兩種情況,P a b c,表明a在b的北邊c那么遠(yuǎn),V a b 表明a在b的北邊(距離最少是1),問(wèn)你這些條件是否沖突。
思路:
? ? ? 一開(kāi)始想用帶權(quán)并查集,先處理P在處理V,想想感覺(jué)不對(duì),還是查分約束吧,查分約束處理這個(gè)題時(shí)間和建圖都簡(jiǎn)單,首先查分約束是根據(jù)最短路(或最長(zhǎng)路)的不等式關(guān)系建圖的,給你一個(gè)圖,跑完最短路對(duì)于邊<a ,b> 會(huì)有dis[b] <= dis[a] + map[a][b];
則 dis[b] - dis[a] <= map[a][b](或者也可以dis[a] - dis[b] >= map[a][b],只不過(guò)這樣要跑最長(zhǎng)路),對(duì)于這個(gè)題目,
V a b ? ?: add(a ,b ,1).
P a b c ?: add(a ,b ,c) ,add(b ,a ,-c).
跑一遍最長(zhǎng)路,或者
V a b ? ?: add(a ,b ,-1).
P a b c ?: add(a ,b ,-c),add(b ,a ,c).
跑一遍最短路。
提醒一點(diǎn)就是別忘記建立超級(jí)原點(diǎn)s,s到每個(gè)點(diǎn)的距離都是0,這樣是為了防止整個(gè)圖不是一個(gè)聯(lián)通快。
#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; }
??
? ? ??
總結(jié)
以上是生活随笔為你收集整理的POJ2983 查分约束系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: POJ2594 最小路径覆盖
- 下一篇: POJ 1961 KMP(当前重复次数)