思路:
- 真是一道神题。
- 讲解:mengxiang000000的BLOG。
- Dijkstra,SPFA找环。
- 把它想成直接给出邻接矩阵,因为是正权图,省去了很多麻烦。需要找出从1到N的最短路,含1的环+含N的环,较小的一个即为答案。需要找环也不是很好想,当然,如果连看成邻接矩阵都想得到,这里估计对你也不是问题。
代码:
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#include <cstdio>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 305;
int N;
int dis[maxn];
int mp[maxn][maxn];
struct NODE{
int id;
int dis;
NODE(int id,int dis) : id(id) , dis(dis) {} ;
friend bool operator > (NODE a , NODE b){
return a.dis > b.dis;
}
};
priority_queue<NODE , vector<NODE> , greater<NODE> > Q;
int IJK(){
memset(dis,INF,sizeof(dis));
Q.push(NODE(1 , 0));dis[1]=0;
while(Q.size()){
NODE cur = Q.top();Q.pop();
if(dis[cur.id] < cur.dis)
continue;
for(int i=1;i<=N;i++){
if(dis[i] > dis[cur.id] + mp[cur.id][i]){
dis[i] = dis[cur.id] + mp[cur.id][i];
Q.push(NODE(i , dis[i]));
}
}
}
return dis[N];
}
queue<int> q;
bool enq[maxn];
int SPFA(int U){
int ans = INF;
memset(dis,INF,sizeof(dis));
memset(enq, 0 ,sizeof(enq));
q.push(U);dis[U]=0;enq[U]=true;
while(q.size()){
int cur = q.front() ; q.pop(); enq[cur] = false;
if(cur != U)
ans = min(ans , dis[cur] + mp[cur][U]);
for(int i=1;i<=N;i++){
if(dis[i] > dis[cur] + mp[cur][i]){
dis[i] = dis[cur] + mp[cur][i];
if(!enq[i]){
q.push(i);
enq[i] = true;
}
}
}
}
return ans;
}
int main(){
while(~scanf("%d",&N)){
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
scanf("%d",&mp[i][j]);
int ans1 = IJK();
int ans2 = SPFA(1) + SPFA(N);
printf("%d\n",min(ans1 , ans2));
}
return 0;
}