poj 3463 (次短路的模版)

来源:互联网 发布:淘宝效果图是啥意思 编辑:程序博客网 时间:2024/06/06 00:38

求最短路数量和和次短路与最短路长度大于1的途径数量。     原来想用第K短路把所有的前面最短的和次短(K=1,2,3,,,,)最后TLE了,不知道A*的复杂度是多少,然后的得用次短路求解,用dp[][2]数组存顶点遍历的次数,Source CodeProblem: 3463 User: 1013101127Memory: 852K Time: 516MSLanguage: G++ Result: AcceptedSource 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;}


原创粉丝点击