UVA 11478 淺談差分約束SPFA判負環
世界真的很大
圖論的演算法是個神奇東西
上次做了這道題就深有感觸了
差分約束也是個差不多的道理,spfa
先看下題吧:
description:
給定一個有向圖,邊有權值,每次操作指定一個點u,一個值d,使所有u的出邊+d,所有入邊-d。問經過數次操作後,最小正邊權最大為多少。如可以無限大就輸出Infinite,如不能為正就輸出No Solution
input
多組資料,輸入到EOF
每組資料第一行包含2個整數n(點),m(邊)
接下來m行每行包含3個整數u,v,w
表示u到v有一條邊權為w的邊
output
每組資料一個輸出表示答案
要求輸出最小的最大,自然想到二分答案
每次二分一個權值val,check能否找到一個方案使所有邊的權值大於val
考慮任意一個點,他的每條入邊和每條出邊的增加(減少)的量肯定是相同的,設為sumi
考慮一條邊(a,b),其操作之後的權值為w(a,b)+suma-sumb ,權值是大於val的,所以:
w(a,b)+suma-sumb > val
移相之後得到:
sumb-suma <= w(a,b)-val
sumb <= w(a,b)-val + suma
這就是差分約束的典型等式了
考慮SPFA中處理的等式
dis[v]< w(u,v) + dis[u]
不是有點相似嗎,這裡w(a,b)-val和w(u,v)都是一個固定的常量,像這樣的這一串式子就可以用像SPFA的方法處理它,如果SPFA能跑出來就說明跑出來了一組可行解,suma就是a點的dis值
如果跑不出來,說明有負環,說明找不到一組可行解
那對於sumb <= w(a,b)-val + suma
我們就連一條a到b,權值為w(a,b)-val的邊,SPFA需要一個源點,因為是單源最短路嘛,所以我們就加一個無關緊要的源點S,使其與所有點連邊,邊權為0
題目規定了上界,所以只要判一下val為最上界是否滿足有解,如果是,就輸出Infinite
題目規定為正數,所以判一下下界1,如果都不行,無解的話就輸出No Solution
完整程式碼:
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int INF=0x3f3f3f3f;
struct edge
{
int v,last,w;
}ed[100010];
queue <int> state;
int head[100010],dis[100010],se[100010],book[100010];
int n,m,ans,num=0,S=0,big=0;
void init()
{
num=0 ,ans=0,S=0,big=0;
memset(head,0,sizeof(head));
}
void add(int u,int v,int w)
{
num++;
ed[num].v=v;
ed[num].w=w;
ed[num].last=head[u];
head[u]=num;
}
bool SPFA()
{
memset(book,0,sizeof(book));
memset(dis,0x3f3f3f3f,sizeof(dis));
memset(se,0,sizeof(se));
while(!state.empty()) state.pop();
state.push(S);
se[S]=1 ,dis[S]=0,book[S]=1;
while(!state.empty())
{
int u=state.front();
se[u]=0;state.pop();
for(int i=head[u];i;i=ed[i].last)
{
int v=ed[i].v;
if(dis[v]>dis[u]+ed[i].w)
{
dis[v]=dis[u]+ed[i].w;
if(!se[v])
{
se[v]=1;
state.push(v);
book[v]++;
if(book[v]>n+1) return 0;
}
}
}
}
return 1;
}
bool check(int val)
{
bool flag;
for(int i=1;i<=num;i++)
ed[i].w-=val;
flag=SPFA();
for(int i=1;i<=num;i++)
ed[i].w+=val;
return flag;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
big=max(big,w);
}
for(int i=1;i<=n;i++)
add(S,i,0);
if(check(big+1))
{
printf("Infinite\n");
continue ;
}
else if(!check(1))
{
printf("No Solution\n");
continue ;
}
int lf=1,rg=big;
while(lf<=rg)
{
int mid=(lf+rg)>>1;
if(check(mid))
{
ans=mid;
lf=mid+1;
}
else rg=mid-1;
}
printf("%d\n",ans);
}
}
/*
Whoso pulleth out this sword from this stone and anvil is duly born King of all England
*/
嗯,就是這樣
相關推薦
UVA 11478 淺談差分約束SPFA判負環
世界真的很大 圖論的演算法是個神奇東西 上次做了這道題就深有感觸了 差分約束也是個差不多的道理,spfa 先看下題吧: description: 給定一個有向圖,邊有權值,每次操作指定一個點u,一個值d,使所有u的出邊+d,所有入邊-d。問經
poj 1364(差分約束+spfa判斷負環)
King Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 12458 Accepted: 4524 Description Once, in one kingdom, there was a
洛谷P3275 [SCOI2011]糖果_差分約束_判負環
Code: #include<cstdio> #include<queue> #include<algorithm> using namespace std; const int N=300000+3; const int I
淺談差分約束問題
最短 HR .html 求解 不難 pos 表示 聯想 html 差分約束 差分約束是解決這樣一類問題 給出\(n\)個形如\(x[j]-x[i]<=k\)的式子,求\(x[n]-x[1]\)的最大/最小值 思路 其實這個問題是挺套路的 我們把給出的式子變一下 \(x
淺談差分約束系統
差分約束系統是個啥呢?可能看名字非常地難理解,其實它要求的就是一個**n元一次不等式組的解**,形式如下: $\begin{cases}x-y \leq 10\\y-z \leq 5\\\end{cases}$ 那麼求解這一組資料的解,就是差分約束系統的目的 那麼對於以上這一個用數學方式來求解的不等
[洛谷 P1993]小K的農場 --- 差分約束 + spfa判環
傳送門:洛谷 P1993 題目描述 小 K K K在
ZOJ 2770 差分約束+SPFA
最大值 multiple sample mea tro output problem igp data Burn the Linked CampTime Limit: 2 Seconds Memory Limit: 65536 KB It is well know
POJ 3159 Candies(差分約束+spfa+鏈式前向星)
void tdi div con pre ace != view ash 題目鏈接:http://poj.org/problem?id=3159 題目大意:給n個人派糖果,給出m組數據,每組數據包含A,B,C三個數,意思是A的糖果數比B少的個數不多於C,即B的糖果數 -
POJ 1364 / HDU 3666 【差分約束-SPFA】
題意 最短 false nbsp DG bsp ont class ast POJ 1364 題解:最短路式子:d[v]<=d[u]+w 式子1:sum[a+b+1]−sum[a]>c — sum[a]<
HDU 1384 Intervals【差分約束-SPFA】
入隊 數組 spf 反向 mem set pac 最大值 can 類型:給出一些形如a−b<=k的不等式(或a−b>=k或a−b<k或a−b>k等),問是否有解【是否有負環】或求差的極值【最短/長路徑】
poj 1201 Intervals【差分約束+spfa】
相反數 ons 最長 using cpp val 註意 interval space 設s為前綴和,首先顯然的條件是\[ s_{bi}-s_{ai-1}>=c \],然後隱含的是\[ s_i-s_{i-1}>=0 s_i-s_{i-1}<=1 \] 然後根
Poj 3169 Layout【差分約束+SPFA】
Layout Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10278 Accepted: 4946 Description Like everyone els
POJ 3169 Layout 差分約束+spfa
Description Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows nu
POJ 1201 差分約束+SPFA
思路: 差分約束,難在建圖。(我是不會告訴你我剛學會SPFA的。。。) 把每個區間的ai–>bi連一條長度為ci的邊。 k–>k+1連一條長度為0的邊。 k+1–>k連一條長度
poj 1364 King(線性差分約束+超級源點+spfa判負環)
King Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 14791 Accepted: 5226 Description Once, in one kingdom, there was a queen and that queen
poj3169 差分約束+spfa
題目連結在這裡 題目大意是有N頭牛,有的牛喜歡相互捱得近一點,有的想相互離得遠一點。輸入的第一行給出三個數N, ML, MD,分別代表N頭牛,有ML條資料是離得近一點,MD條資料是離得遠一點。接下來有ML + MD條資料,每條資料有a b c三個數,代表牛a和牛b離得不超過(或者最少是)c。問第
UVA 558 Wormholes 【SPFA 判負環】
math.h struct possible sta clas ack names dsm 推斷 題目鏈接: https://uva.onlinejudge.org
POJ-1860 Currency Exchange 【spfa判負環】
exchange call ant 代碼 while sim api where class Description Several currency exchange points are working in our city. Let us suppose that
洛谷P3385 【模板】負環 DFS-SPFA 判負環 圖論
string inf scan space can 清空 span %d pre 洛谷P3385 【模板】負環 圖論 今天get了 一個 DFS-SPFA 判負環的方法 一般的 BFS-SPFA 判負環 一般就是 不停地做,如果某點第 n+1次加入隊列中,那麽說明這個圖存在
[poj3259]Wormholes(spfa判負環)
隊列 spfa算法 oid math num nbsp poj3259 pre ash 題意:有向圖判負環。 解題關鍵:spfa算法+hash判負圈。 負圈是指圈上的總和小於0 #include<cstdio> #include<cstring