求最短路和次短路条数,模板
题意:求A~B最短路和C~D最短路的最大交点数量。
N<300。M<N*N。
i→j在两条最短路内当且仅当dis[A][i]+dis[i][j]+dis[j][B]=dis[A][B]
而且dis[C][i]+dis[i][j]+dis[j][D]=dis[C][D]
跑floyd然后N^2枚举,取最长连续公共路径。
答案就等于这个加一。为什么?
因为最长路径一定连续。(重边不考虑)
A→B,C→D里面的点i和j,它们之间的路径i→j一定是i到j的最短路。
所以要取到最多公共点当然要取连续路径啦
---------------------
hdu3191+hdu1688(求最短路和次短路条数,模板)
hdu3191题意:求出次短路的长度和条数
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #include<vector> 6 using namespace std; 7 const int MAXN=55; 8 const int inf=1<<30; 9 struct Edge{ 10 int v,w; 11 }; 12 vector<Edge>vet[MAXN]; 13 struct Node{ 14 int v,dist; 15 int mark;//标记,1为最短路,2为次短路; 16 bool operator < (const Node &p) const { 17 if(p.dist!=dist) 18 return p.dist<dist; 19 20 return p.v<v;//这儿如果不按顶点的大小排序,就wa了。 21 } 22 }; 23 int n,m,s,e; 24 int dist[MAXN][3]; 25 int dp[MAXN][3]; 26 bool visited[MAXN][3]; 27 //dp[i][1]表示到达点i最短的路有多少条,dp[i][2]表示次短的条数 28 //dist[i][1]表示到达点i最短路的长度,dist[i][2]表示次短路的长度 29 /* 30 用v去松驰u时有四种情况 (设当前dist[v][cas]) 31 情况1:dist[v][cas]+w(v,u)<dist[u][1],找到一个更短的距离,则把原来最短的距离作为次短的距离,同时更新最短的.即 32 dist[u][2]=dist[u][1] 33 dist[u][1]=dist[v][cas]+w(v,u); 34 dp[u][2]=dp[u][1] 35 dp[u][1]=dp[v][cas], 36 把Node(dist[u][1],u,1)和Node(dist[u][2],u,2)放入队列 37 情况2:dist[v][cas]+w(v,u)==dist[u][1],找到一条新的相同距离的最短路,则dp[u][1]+=dp[v][cas],其他不用更新,也不入队 38 情况3:dist[v][cas]+w(v,u)<dist[u][2],不可以更新最短距离,但可以更新次短的,则更新dist[u][2]和dp[u][2] 39 dist[u][2]=dist[v][cas]+w(v,u); 40 dp[u][2]=dp[v][cas]; 41 把Node(dist[u][2],u,2)放入队列 42 情况4:dist[v][cas]+w(v,u)==dist[u][2] 找到一条新的相同距离的次短路,则dp[u][2]+=dp[v][cas],其他不更新。 43 */ 44 45 46 47 void Dijkstra(int start,int end){ 48 for(int i=0;i<n;i++){ 49 dist[i][1]=dist[i][2]=inf; 50 } 51 memset(dp,0,sizeof(dp)); 52 memset(visited,false,sizeof(visited)); 53 priority_queue<Node>Q; 54 Node p,q; 55 dist[start][1]=0; 56 dp[start][1]=1; 57 p.dist=0,p.mark=1,p.v=start; 58 Q.push(p); 59 while(!Q.empty()){ 60 p=Q.top(); 61 Q.pop(); 62 if(visited[p.v][p.mark])continue; 63 //if(dist[p.v][p.mark]!=p.dist)continue; 64 visited[p.v][p.mark]=true; 65 for(int i=0;i<vet[p.v].size();i++){ 66 int v=vet[p.v][i].v; 67 int w=vet[p.v][i].w; 68 if(!visited[v][1]&&p.dist+w<dist[v][1]){ 69 //可能为次短路 70 if(dist[v][1]!=inf){ 71 q.v=v,q.dist=dist[v][1],q.mark=2; 72 dist[v][2]=dist[v][1]; 73 dp[v][2]=dp[v][1]; 74 Q.push(q); 75 } 76 dist[v][1]=p.dist+w; 77 dp[v][1]=dp[p.v][p.mark]; 78 q.v=v,q.dist=dist[v][1],q.mark=1; 79 Q.push(q); 80 }else if(!visited[v][1]&&p.dist+w==dist[v][1]){ 81 dp[v][1]+=dp[p.v][p.mark]; 82 }else if(!visited[v][2]&&p.dist+w<dist[v][2]){ 83 dist[v][2]=p.dist+w; 84 dp[v][2]=dp[p.v][p.mark]; 85 q.dist=dist[v][2],q.v=v,q.mark=2; 86 Q.push(q); 87 }else if(!visited[v][2]&&p.dist+w==dist[v][2]){ 88 dp[v][2]+=dp[p.v][p.mark]; 89 } 90 } 91 } 92 } 93 94 95 96 int main(){ 97 while(~scanf("%d%d%d%d",&n,&m,&s,&e)){ 98 for(int i=0;i<n;i++)vet[i].clear(); 99 for(int i=1;i<=m;i++){ 100 int u,v,w; 101 scanf("%d%d%d",&u,&v,&w); 102 Edge p; 103 p.v=v,p.w=w; 104 vet[u].push_back(p); 105 } 106 Dijkstra(s,e); 107 printf("%d %d\n",dist[e][2],dp[e][2]); 108 } 109 return 0; 110 }
hdu1688
题意:求出最短路的条数比最短路大1的次短路的条数和,基本和上题一样,只是最后多了一个判断是否dist[e][1]+1==dist[e][2];
1 #include<iostream> 2 #include<cstdio> 3 #include<vector> 4 #include<queue> 5 using namespace std; 6 const int MAXN=1000+10; 7 const int inf=1<<30; 8 struct Edge{ 9 int v,w; 10 }; 11 vector<Edge>vet[MAXN]; 12 struct Node{ 13 int v,dist; 14 int mark; 15 bool operator < (const Node &p)const { 16 return p.dist<dist; 17 } 18 }; 19 int dist[MAXN][3]; 20 int dp[MAXN][3]; 21 bool visited[MAXN][3]; 22 int n,m,s,e; 23 24 25 void Dijkstra(int start,int end){ 26 for(int i=1;i<=n;i++){ 27 dist[i][1]=dist[i][2]=inf; 28 } 29 memset(visited,false,sizeof(visited)); 30 memset(dp,0,sizeof(dp)); 31 dist[start][1]=0; 32 dp[start][1]=1; 33 priority_queue<Node>Q; 34 Node p,q; 35 p.dist=0,p.mark=1,p.v=start; 36 Q.push(p); 37 while(!Q.empty()){ 38 p=Q.top(); 39 Q.pop(); 40 if(visited[p.v][p.mark])continue; 41 visited[p.v][p.mark]=true; 42 for(int i=0;i<vet[p.v].size();i++){ 43 int v=vet[p.v][i].v; 44 int w=vet[p.v][i].w; 45 if(!visited[v][1]&&p.dist+w<dist[v][1]){ 46 if(dist[v][1]!=inf){ 47 dist[v][2]=dist[v][1]; 48 dp[v][2]=dp[v][1]; 49 q.v=v,q.dist=dist[v][2],q.mark=2; 50 Q.push(q); 51 } 52 dist[v][1]=p.dist+w; 53 dp[v][1]=dp[p.v][p.mark]; 54 q.dist=dist[v][1],q.v=v,q.mark=1; 55 Q.push(q); 56 }else if(!visited[v][1]&&p.dist+w==dist[v][1]){ 57 dp[v][1]+=dp[p.v][p.mark]; 58 }else if(!visited[v][2]&&p.dist+w<dist[v][2]){ 59 dist[v][2]=p.dist+w; 60 dp[v][2]=dp[p.v][p.mark]; 61 q.v=v,q.dist=dist[v][2],q.mark=2; 62 Q.push(q); 63 }else if(!visited[v][2]&&p.dist+w==dist[v][2]){ 64 dp[v][2]+=dp[p.v][p.mark]; 65 } 66 } 67 } 68 } 69 70 71 int main(){ 72 int _case; 73 scanf("%d",&_case); 74 while(_case--){ 75 scanf("%d%d",&n,&m); 76 for(int i=1;i<=n;i++)vet[i].clear(); 77 for(int i=1;i<=m;i++){ 78 int u,v,w; 79 scanf("%d%d%d",&u,&v,&w); 80 Edge p; 81 p.v=v,p.w=w; 82 vet[u].push_back(p); 83 } 84 scanf("%d%d",&s,&e); 85 Dijkstra(s,e); 86 if(dist[e][1]+1==dist[e][2]){ 87 printf("%d\n",dp[e][1]+dp[e][2]); 88 }else 89 printf("%d\n",dp[e][1]); 90 } 91 return 0; 92 }