Floyd算法是穷举图中所有中转点,不断优化起点到终点的距离,可以用来求多源最短路问题和传递闭包。
H——Cow Contest
N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a programming contest. As we all know, some cows code better than others. Each cow has a certain constant skill rating that is unique among the competitors.
The contest is conducted in several head-to-head rounds, each between two cows. If cow A has a greater skill level than cow B (1 ≤ A ≤ N; 1 ≤ B ≤ N; A ≠B), then cow A will always beat cow B.
Farmer John is trying to rank the cows by skill level. Given a list the results of M (1 ≤ M ≤ 4,500) two-cow rounds, determine the number of cows whose ranks can be precisely determined from the results. It is guaranteed that the results of the rounds will not be contradictory.
Input
* Line 1: Two space-separated integers: N and M
* Lines 2..M+1: Each line contains two space-separated integers that describe the competitors and results (the first integer, A, is the winner) of a single round of competition: A and B
Output
* Line 1: A single integer representing the number of cows whose ranks can be determine
#include<iostream> #include<cstring> #include<algorithm> #include<iomanip> #include<cmath> #include<cstdio> #include<vector> using namespace std; #define MAXN 101 #define INF 0x3f3f3f3f /* 9 03 9 11 学习Floyd算法 */ bool win[MAXN][MAXN]; int n,m; int main() { while(scanf("%d%d",&n,&m)==2) { int x,y; for(int i=0;i<m;i++) { scanf("%d%d",&x,&y); win[x][y] = true; } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(win[i][k]&&win[k][j]) win[i][j] = true; int ans = 0,t; for(int i=1;i<=n;i++) { for(t=1;t<=n;t++) { if(t==i) continue; if(!win[i][t]&&!win[t][i]) break; } if(t>n) ans++; } cout<<ans<<endl; } return 0; }
I - Arbitrage
相当于判断有无正环,Floyd.
#include<iostream> #include<cstring> #include<algorithm> #include<iomanip> #include<cmath> #include<cstdio> #include<vector> #include<string> #include<map> using namespace std; #define MAXN 31 #define INF 0x3f3f3f3f /* map<string,int> 确定位置 超时 12 23 12 47 */ int n,m; map<string,int> Mp; double g[MAXN][MAXN]; void Floyd() { for(int k=0;k<n;k++) for(int i=0;i<n;i++) for(int j=0;j<n;j++) { g[i][j] = max(g[i][j],g[i][k]*g[k][j]); } } int main() { int cnt = 0; while(scanf("%d",&n),n) { Mp.clear(); for(int i=0;i<n;i++) for(int j=0;j<n;j++) { if(j==i) g[i][j] = 1.0; else g[i][j] = 0.0; } string str,t1,t2; double rate; for(int i=0;i<n;i++) { cin>>str; Mp[str] = i; } scanf("%d",&m); for(int i=0;i<m;i++) { cin>>t1>>rate>>t2; g[Mp[t1]][Mp[t2]] = rate; } Floyd(); bool f= false; printf("Case %d: ",++cnt); for(int i=0;i<n;i++) if(g[i][i]>1.0) { f = true; cout<<"Yes "; break; } if(!f) cout<<"No "; } return 0; }