poj 3463 (次短路的模版)

求最短路数量和和次短路与最短路长度大于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;
}


你可能感兴趣的:(poj 3463 (次短路的模版))