poj 3463 最短路+次短路

独立写查错不能,就是维护一个次短路的dist

题意:给定一个有向图,问从起点到终点,最短路+比最短路距离长1的路的个数。

Sample Input
2
5 8
1 2 3
1 3 2
1 4 5
2 3 1
2 5 3
3 4 2
3 5 4
4 5 3
1 5
5 6
2 3 1
3 2 1
3 1 10
4 5 2
5 2 7
5 2 7
4 1

Sample Output
3
2

2015-05-14

  1 #include<cstdio>

  2 #include<iostream>

  3 #include<algorithm>

  4 #include<cstring>

  5 #include<cmath>

  6 #include<queue>

  7 #include<map>

  8 using namespace std;

  9 #define MOD 1000000007

 10 const int INF=0x3f3f3f3f;

 11 const double eps=1e-5;

 12 typedef long long ll;

 13 #define cl(a) memset(a,0,sizeof(a))

 14 #define ts printf("*****\n");

 15 const int MAXN=1005;

 16 int n,m;

 17 #define typec int

 18 int tot,src,des;

 19 int head[MAXN],cnt[MAXN][2],dist[MAXN][2],vis[MAXN][2];//dis[i][0]为最短路,dis[i][1]为次短路

 20 struct Edge

 21 {

 22     int to,next,w;

 23 }edge[MAXN*10];

 24 void addedge(int u,int v,int w)

 25 {

 26     edge[tot].to=v;

 27     edge[tot].w=w;

 28     edge[tot].next=head[u];

 29     head[u]=tot++;

 30 }

 31 void init()

 32 {

 33     memset(head,-1,sizeof(head));

 34     tot=0;

 35 }

 36 int dij()

 37 {

 38     int flag;

 39     memset(dist,0x3f,sizeof(dist));

 40     cl(vis);

 41     cl(cnt);

 42     dist[src][0]=0;

 43     cnt[src][0]=1;

 44     for(int j=1;j<2*n;j++)

 45     {

 46         int u;

 47         int Min=INF;

 48         for(int i=1;i<=n;i++)

 49             if(!vis[i][0]&&dist[i][0]<Min)   //找到比最短路还短的路

 50             {

 51                 u=i;

 52                 flag=0;

 53                 Min=dist[i][0];

 54             }

 55             else if(!vis[i][1]&&dist[i][1]<Min)  //说明比最短路长,比次短路短

 56             {

 57                 u=i;

 58                 flag=1;

 59                 Min=dist[i][1];

 60             }

 61         if(u==-1)break;

 62         vis[u][flag]=true;

 63         for(int i=head[u];i!=-1;i=edge[i].next)

 64         {

 65             int v=edge[i].to;

 66             int w=edge[i].w+Min;

 67             if(dist[v][0]>w) //如果找到的新的值比最短路小,则更新最短路和次短路的值

 68             {

 69                 dist[v][1]=dist[v][0];//更新次短路

 70                 dist[v][0]=w;// 更新最短路

 71                 cnt[v][1]=cnt[v][0];

 72                 cnt[v][0]=cnt[u][flag];//更新最短路和次短路的个数

 73 

 74             }

 75             else if(dist[v][0]==w)   //如果值等于最短路

 76                 cnt[v][0]+=cnt[u][flag];//更新最短路的个数

 77             else if(dist[v][1]>w)    //如果找到的值小于次短路的值,更新次短路

 78             {

 79                 dist[v][1]=w;    //更新次短路的值

 80                 cnt[v][1]=cnt[u][flag];  //更新次短路的个数

 81             }

 82             else if(dist[v][1]==w)   //如果找到的值等于次短路的值

 83                 cnt[v][1]+=cnt[u][flag];//更新次短路的个数

 84         }

 85     }

 86     if(dist[des][0]+1==dist[des][1])//如果次短路的值等于最短路值+1

 87         cnt[des][0]+=cnt[des][1];

 88     return cnt[des][0];

 89 }

 90 int main()

 91 {

 92     int tt,u,v,w;

 93     #ifndef ONLINE_JUDGE

 94     freopen("1.in","r",stdin);

 95     #endif

 96     scanf("%d",&tt);

 97     while(tt--)

 98     {

 99         init();

100         scanf("%d%d",&n,&m);

101         while(m--)

102         {

103             scanf("%d%d%d",&u,&v,&w);

104             addedge(u,v,w);

105         }

106         scanf("%d%d",&src,&des);

107         int ans=dij();

108         printf("%d\n",ans);

109     }

110     return 0;

111 }

 

 

2015-1-30:

 1 #include<stdio.h>

 2 #include<string.h>

 3 #include<stdlib.h>

 4 #include<queue>

 5 #define VM 1005

 6 #define EM 10010

 7 using namespace std;

 8 const int inf=0x3f3f3f3f;

 9 int head[VM],cnt[VM][2],dist[VM][2],vis[VM][2];//dis[i][0]为最短路,dis[i][1]为次短路

10 int e,src,des,n,m;

11 struct E

12 {

13     int to,w,next;

14 } edge[EM];

15 void add(int cu,int cv,int cw)

16 {

17     edge[e].to=cv;

18     edge[e].w=cw;

19     edge[e].next=head[cu];

20     head[cu]=e ++;

21 }

22 int dij()

23 {

24     int i,j,u,min,flag;

25     memset(dist,0x3f,sizeof(dist));

26     memset(vis,0,sizeof(vis));

27     memset(cnt,0,sizeof(cnt));

28     dist[src][0]=0;

29     cnt[src][0]=1;

30     for(i=1;i<2*n;i++)

31     {

32         min=inf;

33         for(j=1;j<=n;j++)           //找新的最短路和次短路

34             if(!vis[j][0]&&dist[j][0]<min)

35             {

36                 u=j;

37                 flag=0;

38                 min=dist[j][0];

39             }

40             else if(!vis[j][1]&&dist[j][1]<min)

41             {

42                 u=j;

43                 flag=1;

44                 min=dist[j][1];

45             }

46         if(min==inf)

47             break;

48         vis[u][flag]=1;

49         for(j=head[u];j!=-1;j=edge[j].next)

50         {

51             int v=edge[j].to;

52             int w=edge[j].w+min;

53             if(dist[v][0]>w) //如果找到的新的值比最短路小,则更新最短路和次短路的值

54             {

55                 dist[v][1]=dist[v][0];//更新次短路

56                 dist[v][0]=w;// 更新最短路

57                 cnt[v][1]=cnt[v][0];

58                 cnt[v][0]=cnt[u][flag];//更新最短路和次短路的个数

59 

60             }

61             else if(dist[v][0]==w)   //如果值等于最短路

62                 cnt[v][0]+=cnt[u][flag];//更新最短路的个数

63             else if(dist[v][1]>w)    //如果找到的值小于次短路的值,更新次短路

64             {

65                 dist[v][1]=w;    //更新次短路的值

66                 cnt[v][1]=cnt[u][flag];  //更新次短路的个数

67             }

68             else if(dist[v][1]==w)   //如果找到的值等于次短路的值

69                 cnt[v][1]+=cnt[u][flag];//更新次短路的个数

70         }

71 

72     }

73     if(dist[des][0]+1==dist[des][1])//如果次短路的值等于最短路值+1

74         cnt[des][0]+=cnt[des][1];

75     return cnt[des][0];

76 }

77 int main()

78 {

79     int T,u,v,w;

80     scanf("%d",&T);

81     while(T--)

82     {

83         scanf("%d%d",&n,&m);

84         memset(head,0xff,sizeof(head));

85         e=0;

86         while(m--)

87         {

88             scanf("%d%d%d",&u,&v,&w);

89             add(u,v,w);

90         }

91         scanf("%d%d",&src,&des);

92         int ans=dij();

93         printf("%d\n",ans);

94     }

95     return 0;

96 }
View Code

 

你可能感兴趣的:(poj)