UVA11090-Going in Cycle!!-最短路
Description
You are given a weighted directed graph with n vertices and m edges. Each cycle in the graph has a
weight, which equals to sum of its edges. There are so many cycles in the graph with different weights.
In this problem we want to find a cycle with the minimum mean.
Input
The first line of input gives the number of cases, N. N test cases follow. Each one starts with two
numbers n and m. m lines follow, each has three positive number a, b, c which means there is an edge
from vertex a to b with weight of c.
O#utput
For each test case output one line containing Case #x: followed by a number that is the lowest mean
cycle in graph with 2 digits after decimal place, if there is a cycle. Otherwise print No cycle found..
Constraints
- n ≤ 50
- a, b ≤ n
- c ≤ 10000000
Sample Input
2
2 1
1 2 1
2 2
1 2 2
2 1 3
Sample Output
Case #1: No cycle found.
Case #2: 2.50
思路
存在一个边数为a的大小为m的圈 –> 边和-am<=0 –> 每个边都-m,判断有没有负环
AC代码
/**************************************
*Source : UVA11090
*Knowledge Point : SSSP
*Author : CSUzick
**************************************/
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <stack>
#include <vector>
#include <queue>
#include <cctype>
#include <cmath>
#include <string>
#include <algorithm>
#include <set>
#include <bitset>
#include <map>
#define INF 0x3f3f3f3f3f3fLL
#define ULL unsigned long long
#define LL long long
#define N 100100
#define eps 10e-9
#define MOD 100000000
#define mem(a,n) memset(a,n,sizeof(a))
#define fread freopen("in.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)
using namespace std;
const double PI=acos(-1.0);
struct Edge{
int from,to,dist;
Edge(int u,int v,int d):from(u),to(v),dist(d){};
};
struct SPFA{
vector<Edge> edges;
vector<int> G[N];
bool inque[N];
double d[N];
int cnt[N];
int n,m;
void init(int n){
this->n=n;
for(int i=0;i<=n;++i){
G[i].clear();
}
edges.clear();
}
void AddEdge(int from,int to,int dist){
edges.push_back(Edge(from,to,dist));
m=edges.size();
G[from].push_back(m-1);
}
bool spfa(double mid){
queue<int> que;
memset(inque,0,sizeof(inque));
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;++i){
que.push(i);
d[i]=0;
}
while(!que.empty()){
int temp=que.front();
if(cnt[temp]==n){
return true;
}
que.pop();
inque[temp]=false;
for(int i=0;i<G[temp].size();++i){
Edge &e=edges[G[temp][i]];
if(d[e.to]>d[temp]+e.dist-mid){
d[e.to]=d[temp]+e.dist-mid;
if(!inque[e.to]){
que.push(e.to);
inque[e.to]=true;
if(++cnt[e.to]>=n) return true;
}
}
}
}
return false;
}
};
SPFA SMF;
int main()
{
int t,kase=0,n,m,u,c,v;
double maxl,high,low,mid;
scanf("%d",&t);
while(kase<t){
maxl=0;
scanf("%d%d",&n,&m);
SMF.init(n);
while(m--){
scanf("%d%d%d",&u,&v,&c);
maxl=max(maxl,(double)c);
SMF.AddEdge(u,v,c);
}
high=maxl+1,low=0;
if(!SMF.spfa(high)){
printf("Case #%d: No cycle found.\n",++kase);
continue;
}
while(high-low>eps){
mid=(low+high)/2;
if(SMF.spfa(mid)){
high=mid;
}else{
low=mid;
}
}
printf("Case #%d: %.2f\n",++kase,mid);
}
return 0;
}
本文介绍了解决UVA11090问题的方法,该问题要求寻找加权有向图中平均权重最小的环。通过调整每条边的权重并使用SPFA算法来检测是否存在负权环,进而确定最小平均权重环。
742

被折叠的 条评论
为什么被折叠?



