题目通道
Solution 1
Dijkstra algorithm
#include<iostream>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<map>
#include<vector>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<ctime>
using namespace std;
#define rep(i,aa,bb) for(register int i=aa;i<=bb;i++)
#define rrep(i,aa,bb) for(register int i=aa;i>=bb;i--)
#define LL long long
#define eps 0.000001
#define inf 0x3f3f3f3f
#define llinf 1e18
#define exp 0.000001
#define pai 3.141592654
#define random(x) rand()%(x)
#define lowbit(x) x&(-x)
inline int read()
{
int x=0,y=1;char a=getchar();while ( a>'9' || a<'0'){if ( a=='-')y=-1;a=getchar();}
while ( a>='0' && a<='9' ){ x=10*x+a-'0'; a=getchar();}return x*y;
}
#define N 1009
int e[N][N]; bool vis[N]; int n,m;
int dis[N];
void dij(){
int mann,u;
rep(i,2,n) dis[i] = e[1][i];
dis[1] = inf;
// dis[1] = inf; rep(i,2,n) dis[i] = -inf;
vis[1] = 1;
for (int ai = 1; ai < n; ai++){
mann = 0;
rep(bi,1,n)
if ( !vis[bi]&&mann<dis[bi])
mann = dis[bi], u = bi;
vis[ u ] = 1;
rep(bi,1,n)
if ( dis[bi] < min( dis[u] , e[u][bi]) )
dis[bi] = min( dis[u] , e[u][bi]);
}
}
int main()
{
// freopen("1.txt","r",stdin);
srand((int)time(0));
// std::ios::sync_with_stdio(false);
int T ; T = read();
rep(aai,1,T){
memset(vis,0,sizeof(vis));
n = read(); m = read();
rep(i,1,n)rep(j,1,n){
if ( j == i ) e[i][j] = inf;
else e[i][j] = -inf;
}
rep(i,1,m){
int a,b,c; a = read(); b = read(); c = read();
e[a][b] = e[b][a] = c;
}
dij();
printf("Scenario #%d:\n%d\n\n",aai,dis[n]);
}
return 0;
}
Some details
第一轮dis必须是合法状态,否则无法转移。
dis状态一定是由最劣,到最优,那么意味着,dis必须由小到大迭代。但是在两条路中更小的那条会限制,dis。
if ( dis[bi] < min( dis[u] , e[u][bi]) )
dis[bi] = min( dis[u] , e[u][bi]);
和
if ( !vis[bi] && dis[bi] < min( dis[u] , e[u][bi]) )
dis[bi] = min( dis[u] , e[u][bi]);
等效,因为,在bi已经是最优了,无法再被更新。
Solution 2
Bellman - ford algorithm.
After using Dijkstra algorithm to solut this question, I find the key of this question,so I use another way to deal with it.
#include<iostream>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<map>
#include<vector>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<ctime>
using namespace std;
#define rep(i,aa,bb) for(register int i=aa;i<=bb;i++)
#define rrep(i,aa,bb) for(register int i=aa;i>=bb;i--)
#define LL long long
#define eps 0.000001
#define inf 0x3f3f3f3f
#define llinf 1e18
#define exp 0.000001
#define pai 3.141592654
#define random(x) rand()%(x)
#define lowbit(x) x&(-x)
inline int read()
{
int x=0,y=1;char a=getchar();while ( a>'9' || a<'0'){if ( a=='-')y=-1;a=getchar();}
while ( a>='0' && a<='9' ){ x=10*x+a-'0'; a=getchar();}return x*y;
}
#define N 1009
int n,m;
int dis[N];
struct node {
int u,v,w;
}e[N*N*2];
int main()
{
// freopen("1.txt","r",stdin);
srand((int)time(0));
// std::ios::sync_with_stdio(false);
int T; T = read();
rep(aai,1,T){
n = read(); m = read();
rep(i,2,n) dis[i] = -inf;
rep(i,1,m){
e[i].u = read(); e[i].v = read(); e[i].w = read();
e[i+m].u = e[i].v; e[i+m].v = e[i].u; e[i+m].w = e[i].w;
if ( e[i].u == 1 )
dis[ e[i].v ] = e[i].w;
if ( e[i].v == 1 )
dis[ e[i].u ] = e[i].w;
}
dis[1] = inf;
for (int k = 1; k <= n-1 ; k++){
for (int i = 1; i <= m*2; i++){
if ( dis[ e[i].v ] < min( dis[ e[i].u ] ,e[i].w ) )
dis[ e[i].v ] = min( dis[ e[i].u ] ,e[i].w );
}
}
printf("Scenario #%d:\n%d\n\n",aai,dis[n]);
}
return 0;
}