[UVA]11478 二分答案+差分约束
2017-07-13 19:39
423 查看
You are given a directed graph G(V; E) with a set of vertices and edges. Each edge (i; j) that connects
some vertex i to vertex j has an integer cost associated with that edge.
De ne the operation Halum(v; d) to operate on a vertex v using an integer d as follows: subtract
d from the cost of all edges that enter v and add d to the cost of every edge that leaves v.
As an example of that operation, consider graph G that has three vertices named (1, 2, 3) and two
edges. Edge (1, 2) has cost -1, and edge (2,3) has cost 1. The operation Halum(2; 3) operates on
edges entering and leaving vertex 2. Thus, edge (1, 2) gets cost -1-(-3)=2 and the edge (2, 3) gets cost
1 + (-3) = -2.
Your goal is to apply the Halum function to a graph, potentially repeatedly, until every edge in the
graph has at least a certain cost that is greater than zero. You have to maximize this cost.
Input
Two space-separated integers per case: V (V 500) and E (E 2700). E lines follow. Each line
represents a directed edge using three space-separated integers (u; v; d). Absolute value of cost can be
at most 10000.
Output
If the problem is solvable, then print the maximum possible value. If there is no such solution print
`No Solution'. If the value can be arbitrary large print `Infinite'
Sample Input
2 1
1 2 10
2 1
1 2 -10
3 3
1 2 4
2 3 2
3 1 5
4 5
2 3 4
4 2 5
3 4 2
3 1 0
1 2 -1
Sample Output
Infinite
Infinite
3
1
第一次做差分约束,碰到了一道不是那么水的题...
怎么check?
我们二分最小边权x.我们设sum[u]为操作在u上的d之和(或加或减,这里的sum则是最终结果)。对于两个点(u,v),若使(u,v)这条边边权>=x(因为x为最小边权),那么我们由sum的定义可以知道操作完最终边权应为 w(a,b)+sum[u]-sum[v] .那么他应该>=x.所以式子变换得 w(a,b)-x+sum[u]>=sum[v].(w(a,b)为a,b之间本身的边权).这个式子变换就等价于spfa里的松弛关系,即三角不等式,便可以连边跑spfa了,代码里我建了超级原点的.
Tips:1.每次check边权减去x要跑完spfa记得加上.
2.多组数据注意memset和变量赋初值.
3.那个松弛式子也可以看成sum(b)-sum(a)<=w(a,b)-x(这就是为什么我说边权每次要减去x).
4.差分约束系统判false是出现负环,即每个点入队超过n次(松弛了所有点还能松弛...必定负环).
The End.
some vertex i to vertex j has an integer cost associated with that edge.
De ne the operation Halum(v; d) to operate on a vertex v using an integer d as follows: subtract
d from the cost of all edges that enter v and add d to the cost of every edge that leaves v.
As an example of that operation, consider graph G that has three vertices named (1, 2, 3) and two
edges. Edge (1, 2) has cost -1, and edge (2,3) has cost 1. The operation Halum(2; 3) operates on
edges entering and leaving vertex 2. Thus, edge (1, 2) gets cost -1-(-3)=2 and the edge (2, 3) gets cost
1 + (-3) = -2.
Your goal is to apply the Halum function to a graph, potentially repeatedly, until every edge in the
graph has at least a certain cost that is greater than zero. You have to maximize this cost.
Input
Two space-separated integers per case: V (V 500) and E (E 2700). E lines follow. Each line
represents a directed edge using three space-separated integers (u; v; d). Absolute value of cost can be
at most 10000.
Output
If the problem is solvable, then print the maximum possible value. If there is no such solution print
`No Solution'. If the value can be arbitrary large print `Infinite'
Sample Input
2 1
1 2 10
2 1
1 2 -10
3 3
1 2 4
2 3 2
3 1 5
4 5
2 3 4
4 2 5
3 4 2
3 1 0
1 2 -1
Sample Output
Infinite
Infinite
3
1
第一次做差分约束,碰到了一道不是那么水的题...
题目大意
就是说你可以进行若干次操作,每次操作将某一点入边权值减少d,出边权值增加d.问在这种情况如何操作使最小的边权最大.题解
每一次操作之间互不影响,所以我们没必要去考虑操作次数,只用考虑最终结果.由于要使最小边权最大,很容易想到二分答案(最小最大问题).怎么check?
我们二分最小边权x.我们设sum[u]为操作在u上的d之和(或加或减,这里的sum则是最终结果)。对于两个点(u,v),若使(u,v)这条边边权>=x(因为x为最小边权),那么我们由sum的定义可以知道操作完最终边权应为 w(a,b)+sum[u]-sum[v] .那么他应该>=x.所以式子变换得 w(a,b)-x+sum[u]>=sum[v].(w(a,b)为a,b之间本身的边权).这个式子变换就等价于spfa里的松弛关系,即三角不等式,便可以连边跑spfa了,代码里我建了超级原点的.
Tips:1.每次check边权减去x要跑完spfa记得加上.
2.多组数据注意memset和变量赋初值.
3.那个松弛式子也可以看成sum(b)-sum(a)<=w(a,b)-x(这就是为什么我说边权每次要减去x).
4.差分约束系统判false是出现负环,即每个点入队超过n次(松弛了所有点还能松弛...必定负环).
The End.
#include<stdio.h> #include<cstring> #include<queue> #define maxn 550 #define clear(a) memset(a,0,sizeof(a)) #define full(a) memset(dis,120,sizeof(a)) using namespace std; int h[maxn],dis[maxn],cnt[maxn],num,n,m,lf,rg,x,y,z,ans; bool vis[maxn]; inline const int read(){ register int f=1,x=0; register char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} return f*x; } struct edge{ int nxt,v,w; }e[maxn*50]; void add(int u,int v,int w){ e[++num].v=v,e[num].nxt=h[u],e[num].w=w,h[u]=num; } bool spfa(){ deque<int> q; clear(vis),clear(cnt),full(dis); dis[0]=0,vis[0]=true,cnt[0]++; q.push_front(0); while(!q.empty()){ int u=q.front();q.pop_front();vis[u]=false; for(int i=h[u];i;i=e[i].nxt){ int v=e[i].v; if(dis[v]>dis[u]+e[i].w){ dis[v]=dis[u]+e[i].w; if(!vis[v]){ if(++cnt[v]>n) return false; if(q.empty()||dis[v]<dis[q.front()]) q.push_front(v); else q.push_back(v); vis[v]=true; } } } } return true; } bool check(int x){ for(int u=1;u<=n;u++) for(int i=h[u];i;i=e[i].nxt) e[i].w-=x; bool The_Final_Problem=spfa(); for(int u=1;u<=n;u++) for(int i=h[u];i;i=e[i].nxt) e[i].w+=x; return The_Final_Problem; } int main(){ while(scanf("%d%d",&n,&m)!=EOF){ clear(h),num=0,lf=1,rg=0; for(int i=1;i<=n;i++) add(0,i,0); for(int i=1;i<=m;i++){ x=read(),y=read(),z=read(); add(x,y,z); if(z>rg) rg=z; } if(check(rg)) {puts("Infinite");continue;} else if(!check(lf)) {puts("No Solution");continue;} while(lf<=rg){ int mid=(lf+rg)>>1; if(check(mid)) ans=mid,lf=mid+1; else rg=mid-1; } while(check(ans+1)) ans++; printf("%d\n",ans); } }
相关文章推荐
- UVA 11478 Halum(二分 + 差分约束)
- UVA 11478 查分约束+二分答案 解题报告
- uva11478 Halum【二分+差分约束】
- UVA 11478(差分约束 + 二分)
- UVA11478 Halum (差分约束)
- UVA 11478 Halum (差分约束)
- UVA 11478 Halum(差分约束)
- UVA 11478 Halum(差分约束)
- poj 1275 Cashier Employment - 差分约束 - 二分答案
- UVA 11478 Halum(差分约束,5级)
- UVA 11478 Halum(差分约束,5级)
- HDU1529 Cashier Employment 题解 【差分约束】【二分答案】
- UVA 11478 Halum(差分约束 SPFA判负环)
- Luogu4926 倍杀测量者(二分答案+差分约束)
- UVA11478 Halum (差分约束)
- UVa 11478 Halum (差分约束)
- 差分约束(Halum操作,UVA 11478)
- uva 11478 Halum(图论-差分约束)
- uva 11478 Halum(图论-差分约束)
- UVA11478 Halum 解题报告【图论】【二分答案】【SPFA】【差分约束系统】