題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=2680
思路:反向建圖,找到從s到各個出發點所用時間
注意:大水體一枚,卡了2天,倒也發現了自己沒注意的地方
說道鄰接表在出現重邊的時候可以不必考慮,因爲在更新的時候只會找到最短的並進行更新,但是前提是。。。要有if的判斷
#include<cstdio>
#include<cstring>
using namespace std;
const int num=1005;
const int inf=100000000;
struct node
{
int u,v,next;
}edge[20005];
int n,m,head[num],dis[num],p[num],e;
void add(int a,int b,int c)
{
edge[e].u=b;
edge[e].v=c;
edge[e].next=head[a];
head[a]=e++;
}
void init()
{
int i;
for(i=0;i<=n;i++)
{
p[i]=0;
dis[i]=inf;
}
}
void prim(int s)
{
int i,t,j,tp;
init();
for(i=head[s];i!=-1;i=edge[i].next)
if(dis[edge[i].u]>edge[i].v) //注意此處必須要有if的判斷,防重邊
dis[edge[i].u]=edge[i].v;
dis[s]=0;
p[s]=1;
for(i=1;i<n;i++)
{
t=inf;
for(j=1;j<=n;j++)
if(p[j]==0&&dis[j]<=t)
{
t=dis[j];
tp=j;
}
p[tp]=1;
for(j=head[tp];j!=-1;j=edge[j].next)
if(p[edge[j].u]==0&&dis[tp]+edge[j].v<dis[edge[j].u])
dis[edge[j].u]=dis[tp]+edge[j].v;
}
}
int main()
{
int i,a,b,c,s,t,ans;
//freopen("in.txt","r",stdin);
while(scanf("%d%d%d",&n,&m,&s)!=EOF)
{
e=0;
memset(head,-1,sizeof(head));
for(i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&c);
add(b,a,c);
}
prim(s);
scanf("%d",&t);
ans=inf;
while(t--)
{
scanf("%d",&a);
if(dis[a]<ans)
ans=dis[a];
}
if(ans<inf)
printf("%d\n",ans);
else
printf("-1\n");
}
return 0;
}
化簡又可以避免該問題的方法:
#include<cstdio>
#include<cstring>
using namespace std;
const int num=1005;
const int inf=0x3fffffff;
struct node
{
int v,dis,next;
}edge[20005];
int n,m,head[num],p[num],dis[num],e;
void add(int a,int b,int c)
{
edge[e].v=b;
edge[e].dis=c;
edge[e].next=head[a];
head[a]=e++;
}
void init()
{
int i;
for(i=0;i<=n;i++)
{
dis[i]=inf;
p[i]=0;
}
}
void dij(int src)
{
int i,k,temp,tp;
dis[src]=0;
p[src]=1;
tp=src;
for(i=1;i<=n;i++)
{
for(k=head[tp];k!=-1;k=edge[k].next)
{
if(p[edge[k].v]==0&&dis[tp]+edge[k].dis<dis[edge[k].v])
dis[edge[k].v]=dis[tp]+edge[k].dis;
}
temp=inf;
for(k=1;k<=n;k++)
{
if(p[k]==0&&dis[k]<temp)
{
temp=dis[k];
tp=k;
}
}
p[tp]=1;
}
}
int main()
{
int i,j,a,b,c,t,ans,s;
//freopen("in.txt","r",stdin);
while(scanf("%d%d%d",&n,&m,&s)!=EOF)
{
e=0;
memset(head,-1,sizeof(head));
while(m--)
{
scanf("%d%d%d",&a,&b,&c);
add(b,a,c);
}
init();
dij(s);
scanf("%d",&t);
ans=inf;
while(t--)
{
scanf("%d",&a);
if(dis[a]<ans)
ans=dis[a];
}
if(ans==inf)
printf("-1\n");
else
printf("%d\n",ans);
}
return 0;
}