题意:求第二短路,题目定义:一定要大于最短路 并且路可以重复走;
开二维数组 d[N][2] 分别记录最短路和第二短路
#include <cstdio> #include <cstring> #include <cstdlib> #include <string> #include <iostream> #include <algorithm> #include <sstream> #include <cmath> using namespace std; #include <queue> #include <stack> #include <set> #include <vector> #include <deque> #include <map> #define cler(arr, val) memset(arr, val, sizeof(arr)) #pragma comment(linker, "/STACK:102400000,102400000") typedef long long LL; const int MAXN = 5010+1; const int MAXM = 240000; const int INF = 0x3f3f3f3f; const int mod = 1000000007; int d[MAXN][2],head[MAXN],tol; bool vis[MAXN][2]; struct node { int u,v,val,next; }edge[MAXM]; void addedge(int u,int v,int w) { edge[tol].u=u,edge[tol].v=v,edge[tol].val=w,edge[tol].next=head[u]; head[u]=tol++; edge[tol].u=v,edge[tol].v=u,edge[tol].val=w,edge[tol].next=head[v]; head[v]=tol++; } void dij(int n) { for(int i=0;i<=n;i++) d[i][0]=d[i][1]=INF,vis[i][0]=vis[i][1]=false; d[0][0]=0; while(true) { int v=-1,k; int minlen=INF; for(int u=0;u<n;u++) { for(int l=0;l<2;l++) if(!vis[u][l]&&(v==-1||d[u][l]<minlen)) { minlen=d[u][l]; k=l; v=u; } } if(v==-1) break; vis[v][k]=true; for(int i=head[v];~i;i=edge[i].next) { int u=edge[i].v;//目标 int cost=d[v][k]+edge[i].val; if(cost<d[u][0]) { d[u][1]=d[u][0]; d[u][0]=cost; } else if(cost<d[u][1]&&cost>d[u][0]) { d[u][1]=cost; } } } } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); #endif int t,n,m,u,v,w,cas=1; cin>>t; while(t--) { cler(head,-1); tol=0; cin>>n>>m; int a=0; for(int i=0;i<m;i++) { scanf("%d%d%d",&u,&v,&w); a=max(a,u); a=max(a,v); u--,v--; addedge(u,v,w); } dij(a); printf("Case %d: %d\n",cas++,d[n-1][1]); } return 0; }
时间: 2024-10-06 01:20:28