这题算是这场考试里最水的一道题了吧,就是求个最小环,但之前没练过,就在考场上yy出了最短路+次短路的傻逼解法,首先是不会求次短路,其次是这显然不对呀,自己随便想想就可以反驳这种解法。
正解比较神,但是跑n遍dijkstra就完全可以了,具体细节看代码吧。

1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<vector> 7 #include<queue> 8 using namespace std; 9 const int N=10005; 10 int first[N],to[N*8],nex[N*8],edge[N*8],tot=1,d[N],v[N]; 11 void add(int a,int b,int c){ 12 to[++tot]=b,edge[tot]=c,nex[tot]=first[a],first[a]=tot; 13 } 14 priority_queue<pair<int ,int > >q; 15 void dij(int k){ 16 memset(d,0x3f,sizeof(d)); 17 memset(v,0,sizeof(v)); 18 q.push(make_pair(0,k)); 19 d[k]=0; 20 while(q.size()){ 21 int x=q.top().second; 22 q.pop(); 23 if(v[x]) continue; 24 v[x]=1; 25 for(int i=first[x];i;i=nex[i]){ 26 int y=to[i],z=edge[i]; 27 if(d[y]>d[x]+z){ 28 d[y]=d[x]+z; 29 q.push(make_pair(-d[y],y)); 30 } 31 } 32 } 33 } 34 void init(){ 35 tot=1; 36 memset(first,0,sizeof(first)); 37 memset(nex,0,sizeof(nex)); 38 memset(to,0,sizeof(to)); 39 } 40 int main(){ 41 int T; 42 scanf("%d",&T); 43 while(T--){ 44 int n,m; 45 scanf("%d%d",&n,&m); 46 init(); 47 for(int i=1;i<=m;i++){ 48 int x,y,z; 49 scanf("%d%d%d",&x,&y,&z); 50 add(x,y,z); 51 add(y,x,z); 52 } 53 int ans=1061109567; 54 for(int i=first[1];i;i=nex[i]){ 55 int z=edge[i],y=to[i]; 56 edge[i]=edge[i^1]=1061109567; 57 dij(1); 58 ans=min(ans,d[y]+z); 59 edge[i]=edge[i^1]=z; 60 } 61 if(ans==1061109567) {puts("-1");continue;} 62 printf("%d ",ans); 63 } 64 }