Description
2012伦敦奥运会就要来了,此次伦敦奥运的火炬将不再进行全球传递,也就是只在本国英国传递。伦敦奥组委计划将火炬传遍英国的各个角落,这下可苦了某些城市的市长,由于欧债危机,他们实在无钱支付火炬传递需要的开销。于是设计一条花费最小的火炬传递路线势在必行。X市的格局很神奇,这个市是一个类似威尼斯的水城,共有n个岛,并且有m条桥连接着它们,这些桥在火炬传递期间只能单向行进,通过每座桥都有一定的费用(包括环境布置等)。火炬传递的路线必须是一个环,也就是说,你可以任意选择一个岛出发,最后必须回到这个岛。现在请你找出花费最小的一条火炬传递路线。
Input
输入第一行包含两个整数n,m,表示岛屿个数和桥的个数。
接下来m行,第i行两个整数,x,y, c,表示可以从岛x经过第i座桥到达岛y,花费为c。
接下来m行,第i行两个整数,x,y, c,表示可以从岛x经过第i座桥到达岛y,花费为c。
Output
输出一行,最小花费。
Sample Input
10 15
8 9 1
6 2 10
2 4 5
3 1 5
1 4 3
6 7 10
2 9 9
1 5 8
10 6 5
3 10 4
8 6 8
6 5 4
6 4 8
3 2 9
7 8 5
8 9 1
6 2 10
2 4 5
3 1 5
1 4 3
6 7 10
2 9 9
1 5 8
10 6 5
3 10 4
8 6 8
6 5 4
6 4 8
3 2 9
7 8 5
Sample Output
23
Hint
对于50%的数据n<=200, m<=2000
对于100%的数据n<=1000, m<=10000
对于100%的数据n<=1000, m<=10000
Source
刘峻琳(详情请看:360百科)
分析
用n遍前向星SPFA实现求出任意2点之间的最短路,然后枚举求答案。PS:read()玄学啊啊啊!!!!!千万不要用addedge(read(),read(),read())!!!!!答案是错的啊啊啊啊啊!!!我找了半个小时错误啊!!!
//题解by disangan233 or Lixiuyu
#include<bits/stdc++.h>
using namespace std;
#define re register long long
#define ll long long
ll cnt,n,m,h[20005],dis[1005][1005],vis[1005],ans=1234567890;
struct did{
ll next,to,l;
}e[20005];
queue<ll>q;//spfa
inline ll read()
{
char did=getchar();
re luoyang=0,yz=1;
while(!isdigit(did)){if(did=='-')yz=-1;did=getchar();}
while(isdigit(did))luoyang=luoyang*10+did-'0',did=getchar();
return yz*luoyang;
}
inline void add(ll x,ll y,ll z)//前向星
{
e[++cnt].to=y;
e[cnt].l=z;
e[cnt].next=h[x];
h[x]=cnt;
}
inline void spfa(ll s)//spfa
{
memset(vis,0,sizeof(vis));
ll g,j;
for(re t=1;t<=n;++t)
dis[s][t]=13145201314;
dis[s][s]=0;
while(!q.empty()) q.pop();
q.push(s);
vis[s]=1;
while(!q.empty())
{
g=q.front();
q.pop();
vis[g]=0;
for(j=h[g];j;j=e[j].next)
{
if(dis[s][e[j].to]>e[j].l+dis[s][g])
{
dis[s][e[j].to]=e[j].l+dis[s][g];
if(!vis[e[j].to])
{
vis[e[j].to]=1;
q.push(e[j].to);
}
}
}
}
}
int main()
{
n=read();m=read();
for(re i=1;i<=m;i++)
{
re x=read(),y=read(),z=read();add(x,y,z);
// add(read(),read(),read());不要用这个!!!!!!!!!!!!!!!!!!!!!!!
}//有向边
for(re i=1;i<=n;i++)
spfa(i);
for(re i=1;i<=n;i++)
for(re j=1;j<=n;j++)
if(i!=j)
ans=min(ans,dis[i][j]+dis[j][i]);
cout<<ans<<endl;
return 0;
}