3 3 0 2 0 2 5 0 1 4 1 2 2
6 1
题意:有n个点,m条有向边,构成有向无环图。问从S点到T点次短路是多少及路的条数。
#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
const int N = 55;
const int INF = 1<<30;
struct EDG
{
int to,next,dis;
} edg[N*N];
struct node
{
int dis,id,mark;
friend bool operator<(node aa,node bb)
{
return aa.dis>bb.dis;
}
};
int eid,head[N];
int dis[N][2],dp[N][2],in[N];
void addEdg(int u,int v,int d)
{
edg[eid].to=v;
edg[eid].dis=d;
edg[eid].next=head[u];
head[u]=eid++;
}
void topesort(int s,int n)
{
queue<int>q;
for(int i=0; i<n; i++)
if(in[i]==0&&i!=s)
{
q.push(i);
}
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u]; i!=-1; i=edg[i].next)
{
int v=edg[i].to;
in[v]--;
if(in[v]==0&&v!=s)
q.push(v);
}
}
for(int i=0; i<n; i++)
for(int j=0; j<2; j++)
dis[i][j]=INF,dp[i][j]=0;
q.push(s);
dis[s][0]=0;
dp[s][0]=1;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int k=0; k<2; k++)
for(int i=head[u]; i!=-1; i=edg[i].next)
{
int v=edg[i].to;
if(dis[u][k]+edg[i].dis<dis[v][0])
{
if(dis[v][0]!=INF)
{
dis[v][1]=dis[v][0];
dp[v][1]=dp[v][0];
}
dis[v][0]=dis[u][k]+edg[i].dis;
dp[v][0]=dp[u][k];
}
else if(dis[u][k]+edg[i].dis==dis[v][0])
dp[v][0]+=dp[u][k];
else if(dis[u][k]+edg[i].dis<dis[v][1])
{
dis[v][1]=dis[u][k]+edg[i].dis;
dp[v][1]=dp[u][k];
}
else if(dis[u][k]+edg[i].dis==dis[v][1])
dp[v][1]+=dp[u][k];
if(in[v])
{
in[v]--;
if(in[v]==0)
q.push(v);
}
}
}
}
int main()
{
int n,m,s,t,u,v,d;
while(scanf("%d%d%d%d",&n,&m,&s,&t)>0)
{
eid=0;
memset(head,-1,sizeof(head));
memset(in , 0, sizeof(in));
while(m--)
{
scanf("%d%d%d",&u,&v,&d);
addEdg(u,v,d);
in[v]++;
}
topesort(s , n);
printf("%d %d\n",dis[t][1],dp[t][1]);
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU 3191How Many Paths Are There(TOPE排序 求次短路及条数)
原文地址:http://blog.csdn.net/u010372095/article/details/46942787