求最短路数量和和次短路与最短路长度大于1的途径数量。
原来想用第K短路把所有的前面最短的和次短(K=1,2,3,,,,)最后TLE了,不知道A*的复杂度是多少,然后的得用次短路求解,用dp[][2]数组存顶点遍历的次数,
Source Code
Problem: 3463 User: 1013101127
Memory: 852K Time: 516MS
Language: G++ Result: Accepted
Source Code
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF=9999999;
struct node
{
int v;
int len;
int next;
}edge[10005];
bool cmp(node a,node b)
{
return a.len<b.len;
}
int cnt;
int head[1003];
int n,m;
int start;
int end;
void init()
{
for(int i=1;i<=n;i++)
head[i]=-1;
cnt=0;
}
void insert(int u,int v,int len)
{
edge[cnt].v=v;edge[cnt].len=len;edge[cnt].next=head[u];
head[u]=cnt;
cnt++;
}
int disj(int S,int E)
{
int i,j;
int v[1002][2];
int dis[1002][2];
int dp[1002][2];//记录顶点遍历的次数,次短路的模版没有这个,
memset(v,0,sizeof(v));
memset(dp,0,sizeof(dp));
for(i = 1;i <= n;i ++)
dis[i][0] = dis[i][1] = INF;
dis[S][0] = 0;
dp[S][0] = 1;
int x,flag;
for(i = 1;i <= n*2;i ++)
{
int min_d = INF;
for(j = 1;j <= n;j ++)
{
if(!v[j][0] && min_d > dis[j][0])
{
min_d = dis[j][0];
x = j;
flag = 0;
}
else if(!v[j][1] && min_d > dis[j][1])
{
min_d = dis[j][1];
x = j;
flag = 1;
}
}
v[x][flag] = 1;
if(min_d == INF) break;
for(j = head[x];j != -1;j = edge[j].next)
{
int len = min_d + edge[j].len,y = edge[j].v;
if(len < dis[y][0])
{
dis[y][1] = dis[y][0];
dp[y][1] = dp[y][0];
dis[y][0] = len;
dp[y][0] = dp[x][flag];
}
else if(len == dis[y][0])
{
dp[y][0] += dp[x][flag];
}
else if(len < dis[y][1])
{
dis[y][1] = len;
dp[y][1] = dp[x][flag];
}
else if(len == dis[y][1])
{
dp[y][1] += dp[x][flag];
}
}
}
int ans;
if(dis[E][0]+1==dis[E][1])//最短路和次短路差一
ans=dp[E][0]+dp[E][1];
else
ans=dp[E][0];
return ans;
}
int main()
{
int cas;
int uu,vv,L;
cin>>cas;
while(cas--)
{
cin>>n>>m;
init();
for(int i=1;i<=m;i++)
{
cin>>uu>>vv>>L;
insert(uu,vv,L);
}
cin>>start>>end;
cout<<disj(start,end)<<endl;
}
return 0;
}