Problem H
|
Halum
|
Time Limit : 3 seconds
| ||
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 | Sample Output | |||
2 1 | Infinite | |||
Problem Setter: Md. Mahbubul Hasan |
思路:设sum(u)是u点所有加减操作的和,那么u->v的最终权值就是sum(u)+w(u,v)-sum(v)
二分最小权值x
那么就是 sum(u)+w(u,v)-sum(v)>=x
sum(v)<=sum(u)+w(u,v)-x 等价于最短路的d[v]<=d[u]+w(u,v);
因此一个差分就可以解决了。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
const int mm=500+9;
const int mn=4700+9;
const int oo=1e9;
int n,m,edge;
int head[mm];
class node
{
public:int v,next,dis;
}e[mn];
void data()
{
memset(head,-1,sizeof(head));edge=0;
}
void add(int u,int v,int _dis)
{
e[edge].v=v;e[edge].dis=_dis;e[edge].next=head[u];head[u]=edge++;
}
int id[mm],dis[mm];bool vis[mm];
bool spfa(int x)
{
int u,v;
memset(vis,0,sizeof(vis));
memset(id,0,sizeof(id));
queue<int>Q;
for(int i=0;i<=n;++i)
dis[i]=oo;
Q.push(0);vis[0]=1;
dis[0]=0;
int z,spend;
while(!Q.empty())
{
u=Q.front();Q.pop();vis[u]=0;
for(int i=head[u];~i;i=e[i].next)
{
v=e[i].v;
spend=e[i].dis-x;
if(dis[v]>dis[u]+spend)
{
dis[v]=dis[u]+spend;
if(!vis[v])
{
if(++id[v]>=n+1)
{return 0;}
vis[v]=1;Q.push(v);
}
}
}
}
return 1;
}
int main()
{ int a,b,c;
while(~scanf("%d%d",&n,&m))
{ data();
for(int i=0;i<m;++i)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}
for(int i=1;i<=n;++i)
add(0,i,0);
int l=0,r=10001,mid,ans=0;
if(spfa(r)){printf("Infinite\n");continue;}
if(!spfa(1)){printf("No Solution\n");continue;}
while(l<=r)
{
mid=(l+r)/2;
if(spfa(mid)){l=mid+1;ans=max(ans,mid);}
else r=mid-1;
}
printf("%d\n",ans);
}
return 0;
}