您的位置:首页 > 其它

poj 3463 Sightseeing 最短路和次短路的总数

2012-02-02 02:32 323 查看
http://poj.org/problem?id=3463

题意:求最短路和比最短路大一个单位的总数

看的这个解题报告http://blog.csdn.net/leeeyupeng/article/details/5790928

二维存储

cnt[MAX][2],visit[MAX][2],dis[MAX][2]; dist[i][0]源点到i点的最短路径,dist[i][1]远点到i的次短路径,visit标记访问情况,cnt[i][0],cnt[i][1]到i点最短路径,次短路径的数量,

还有就是经典的

更新路径数量的方法

if val<dis[i][0]

else if val==dis[i][0]

else if val<dis[i][1]

else if val==dis[i][1]

具体代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#define inf 1<<30
#define MAX 1002
using namespace std;
int head[MAX],cnt[MAX][2],vs[MAX][2],dis[MAX][2];
int n,s_edge,S,T;
struct Edge
{
int to,w,next;
}edge[MAX*10];

void addedge(int u,int v,int w)
{
s_edge++;
edge[s_edge].to=v;
edge[s_edge].w=w;
edge[s_edge].next=head[u];
head[u]=s_edge;
return ;
}

void dijkstra()
{
int i,mark,flag,MIN,k,j;
for(i=1;i<=n;i++)
dis[i][0]=inf, dis[i][1]=inf;
memset(vs,0,sizeof(vs));
memset(cnt,0,sizeof(cnt));
dis[S][0]=0;
cnt[S][0]=1;

for(k=1;k<2*n;k++)
{
MIN=inf;
for(j=1;j<=n;j++)
{
if(!vs[j][0]&&dis[j][0]<MIN)
MIN=dis[j][0],mark=j,flag=0;
if(!vs[j][1]&&dis[j][1]<MIN)
MIN=dis[j][1],mark=j,flag=1;
}

if(MIN==inf)break;//!!!
vs[mark][flag]=1;
//!!!
int e,v,val;
for(e=head[mark];e;e=edge[e].next)
{
v=edge[e].to;
val=MIN+edge[e].w;

if(val<dis[v][0])
{
dis[v][1]=dis[v][0];
cnt[v][1]=cnt[v][0];
dis[v][0]=val;
cnt[v][0]=cnt[mark][flag];
}
else if(val==dis[v][0])
cnt[v][0]+=cnt[mark][flag];

else if(val<dis[v][1])
{
dis[v][1]=val;
cnt[v][1]=cnt[mark][flag];
}
else if(val==dis[v][1])
cnt[v][1]+=cnt[mark][flag];
}
}
return ;
}

int main()
{
int CASE;
scanf("%d",&CASE);
while(CASE--)
{
int m,u,v,w;
scanf("%d%d",&n,&m);
memset(head,0,sizeof(head));
s_edge=0;
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
scanf("%d%d",&S,&T);
dijkstra();
if(dis[T][1]==dis[T][0]+1)
{
printf("%d\n",(cnt[T][1]+cnt[T][0]));
}
else printf("%d\n",cnt[T][0]);
}
return 0;
}


  

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: