标签:
独立写查错不能,就是维护一个次短路的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 }
标签:
原文地址:http://www.cnblogs.com/cnblogs321114287/p/4263009.html