题目链接:http://210.32.82.1/acmhome/problemdetail.do?&method=showdetail&id=3744
这道题对我而言有点难度...一开始想不好怎么去判断....然后发现可以找到从起点/终点出发到每个点的最短路,这样遍历之后,就可以空缺一条边作为“免费”的,然后得到最小值就可以了。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <cstring>
using namespace std;
const int INF = 0x7fffffff;
const int maxn = 110;
vector<pair<int, int> > g[maxn+10];
bool inque[maxn+10];
void spfa(int s, int d[])
{
queue<int> Q;
int i;
for(i=1;i<maxn;i++)
d[i]=INF;
d[s]=0;
while(!Q.empty())
Q.pop();
Q.push(s);
inque[s]=true;
while(!Q.empty())
{
int u=Q.front();
Q.pop();
for(i=0;i<g[u].size();i++)
{
int t=g[u][i].first;
if(d[u]+g[u][i].second<d[t])
{
d[t]=d[u]+g[u][i].second;
if(!inque[t])
{
inque[t]=true;
Q.push(t);
}
}
}
inque[u]=false;
}
}
int main()
{
int i,j,x,u,v,w,gn,gm;
int d1[maxn],d2[maxn];
pair<int,int> t;
while(scanf("%d%d",&gn,&gm) != EOF)
{
for(i=1;i<=gn;i++)
g[i].clear();
for(i=1;i<=gm;i++)
{
scanf("%d%d%d",&u,&v,&w);
t.first=v;
t.second=w;
g[u].push_back(t);
t.first=u;
t.second=w;
g[v].push_back(t);
}
//计算起点/终点到每个点的最短路,然后遍历
spfa(1,d1);
spfa(gn,d2);
int mindis=INF;
for(i=1;i<=gn;i++)
{
for(j=0;j<g[i].size();j++)
{
x=g[i][j].first;
if(d1[i]!=INF&&d2[i]!=INF&&d1[i]+d2[x]<mindis)
mindis=d1[i]+d2[x];
}
}
if(mindis!=INF)
printf("%d\n",mindis);
else
printf("-1\n");
}
return 0;
}