给一个点加D,的效果为以从该点发出的出边权值+D,所有进入该边的入边权值-D,现在要求使所有边权值为正,且最大的D。
sum(a)表示节点a上D值之和
得到不等式 对于<a,b> sum(a)-sum(b)+w(a,b)>=D 可以得到这个不等式,不等式怎么办?差分约束,最短路。注意要是图联通。所以加入0与每个点连权值为0
最后二分枚举D,判断是否有负环,有则不符合要求。
Time Limit: 3000MS | Memory Limit: Unknown | 64bit IO Format: %lld & %llu |
Description
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 |
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
#define MAXN 600
#define INF 0x3f3f3f3f
struct node
{
int to,dis;
int next;
}edge[999999];
bool in[MAXN];
int s[MAXN];
int cnt[MAXN];
int head[MAXN],en;
int n,m,dis[MAXN];
int maxs;
void add(int u,int v,int d)
{
edge[en].to=v;
edge[en].dis=d;
edge[en].next=head[u];
head[u]=en++;
}
bool spfa(int s)
{
queue<int> q;
for(int i=0;i<=n;i++)
{
dis[i]=INF;
in[i]=false;
cnt[i]=0;
}
dis[s]=0;
in[s]=true;
cnt[s]++;
q.push(s);
while(!q.empty())
{
int u=q.front();
in[u]=false;
q.pop();
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(dis[u]+edge[i].dis<dis[v])
{
dis[v]=dis[u]+edge[i].dis;
if(!in[v])
{
q.push(v);
in[v]=true;
if(++cnt[v]>=n+1)
return false;
}
}
}
}
return true;
}
bool jud(int x)
{
bool ok=1;
for(int i=0;i<=n;i++)
for(int j=head[i];j!=-1;j=edge[j].next)
edge[j].dis-=x;
if(!spfa(0)) ok=0;
for(int i=0;i<=n;i++)
for(int j=head[i];j!=-1;j=edge[j].next)
edge[j].dis+=x;
return ok;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
memset(head,-1,sizeof(head));en=0;
int u,v,x;
maxs=-0x3f3f3f3;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&x);
add(u,v,x);
maxs=max(maxs,x);
}
for(int i=1;i<=n;i++)
add(0,i,0);
if(jud(maxs+1)) printf("Infinite\n");
else if(!jud(1)) printf("No Solution\n");
else
{
int mid,l=1,r=maxs,ans=1;
while(l<=r)
{
mid=(l+r)>>1;
if(jud(mid))
{
ans=mid;
l=mid+1;
}
else
r=mid-1;
}
printf("%d\n",ans);
}
}
return 0;
}
Time Limit: 3000MS | Memory Limit: Unknown | 64bit IO Format: %lld & %llu |
Description
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 |