题目大意是给出一个图,求出经过的最长边最短的最短路径。
方法是把边从小到大排序以此加入图中知道原点和目的点连同为止,然后SPFA 一遍完成。
不知为何一边做并查集一边加边就会WA, 做完了并查集之后一并加进去就A 了_(:3J L)_
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
#define inf 1000000009
queue<int> q;
int s[2005],dis[2005],f[2005];
bool vis[2005];
int n,m,en,a,b,u,v,w;
int ff(int a){
return (f[a]==a)?a:(f[a]=ff(f[a]));
}
struct edge{
int v,w,nxt;
}es[100005];
struct eds{
int u,v,w;
}ss[100005];
bool cmp(eds a,eds b){
return a.w<=b.w;
}
void add_edge(int u,int v,int w){
es[++en].v=v;
es[en].w=w;
es[en].nxt=s[u];
s[u]=en;
}
void spfa(int a){
int p;
memset(vis,0,sizeof(vis));
while(!q.empty()) q.pop();
for(int i=1;i<=n;i++) dis[i]=inf;
vis[a]=1; dis[a]=0;
q.push(a);
while(!q.empty()){
p=q.front();
q.pop();
for(int i=s[p];i;i=es[i].nxt)
if(dis[p]+es[i].w < dis[es[i].v]){
dis[es[i].v]=dis[p]+es[i].w;
if(!vis[es[i].v]){
vis[es[i].v]=1;
q.push(es[i].v);
}
}
vis[p]=0;
}
return ;
}
int main(){
while(scanf("%d%d%d%d",&n,&m,&a,&b)!=EOF){
for(int i=0;i<m;i++)
scanf("%d%d%d",&ss[i].u,&ss[i].v,&ss[i].w);
sort(ss,ss+m,cmp);
for(int i=1;i<=n;i++) f[i]=i;
for(int i=0;i<m;i++){
f[ff(ss[i].u)]=ff(ss[i].v);
if(ff(a)==ff(b)){
w=ss[i].w;
break;
}
}
en=0;
memset(s,0,sizeof(s));
for(int i=0;i<m && ss[i].w<=w;i++){
add_edge(ss[i].u,ss[i].v,ss[i].w);
add_edge(ss[i].v,ss[i].u,ss[i].w);
}
spfa(a);
printf("%d\n",dis[b]);
}
return 0;
}
/**************************************************************
Problem: 1307
User: alpc_feline
Language: C++
Result: Accepted
Time:64 ms
Memory:3436 kb
****************************************************************/