刘儒家的原题..还有不要看刘汝佳的傻逼翻译他说是非负然而题目是大于0,rlg了不然lz一a!!
//易错点注意是负还是非负!!!!!
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
struct edgee
{
int to;
int value;
};
edgee edge[8000];
int edgetot;
int first[1000], nextt[8000],times[1000],isinque[2000];
int dist[1000];
int n, m;
void addedge(int a, int b, int c)
{
edge[edgetot].to = b;
edge[edgetot].value = c;
nextt[edgetot] = first[a];
first[a] = edgetot;
edgetot++;
}
bool spfa()
{
queue<int>que;
for (int i = 1; i <= n; i++)dist[i] = 0, times[i] = 0, isinque[i] = 1, que.push(i);
while (!que.empty())
{
int temp = que.front();
que.pop();
isinque[temp] = 0;
for (int i = first[temp]; i!=-1; i = nextt[i])
{
int to = edge[i].to;
if (dist[to] > dist[temp] + edge[i].value)
{
dist[to] = dist[temp] + edge[i].value;
if (!isinque[to])
{
times[to]++;
isinque[to] = 1;
que.push(to);
if (times[to] == n + 1)return true;
}
}
}
}
return false;
}
bool control(int value, int kind)
{
for (int i = 0; i < edgetot; i++)edge[i].value -= value, edge[i].value*=kind;
bool k = spfa();
for (int i = 0; i < edgetot; i++)edge[i].value *= kind, edge[i].value += value;//这一定要注意顺序~!
return k;
}
int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = 1; i <= n; i++)first[i] = -1;
edgetot = 0;
int l = 99999999, r = -99999999;
for (int i = 0; i < m; i++)
{
int a, b;
int c;
scanf("%d%d%ld", &a, &b, &c);
addedge(a, b, c);
l = min(l, c);
r = max(r, c);
}
//l = 1;
if (m == 0||n==0)
{
printf("No Solution\n");
continue;
}
if (!control(r + 1, 1))
{
printf("Infinite\n");
continue;
}
if (control(1, 1))//证明有负环,注意这里最小值是非负所以>=1,如果是0都是错的!!!!
{
printf("No Solution\n");
continue;
}
while (r - l > 1)
{
int mid = (l + r) / 2;
bool k = control(mid,1);
//cout << "mid:" << mid << " " << "K:" << k << endl;
if (k)
r = mid;
else
l = mid;
//cout << "l:" << l << " " << "r:" << r << endl;
}
if (control(r, 1))
printf("%d\n", l);
else
printf("%d\n", r);
}
return 0;
}