Description
Input
Output
Sample Input
6 6 1 2 1 2 3 1 3 4 1 4 5 1 1 5 2 4 6 3 1 6 2 4 0 0
Sample Output
3 Hint: One possible arrangement is (1-2-3-4-6) for Wukong and (2-3-4) for Tang Monk. The number of common points are 3.
先跑出最短路:如果 dis[a]+edge[a][b]==dis[b] 说明 ab可以可以是最短路上的边。所已用DP
dp[a][b] 从两起点到ab的最优值。
注意 起点一样,以及重边。
#include<cstdio> #include<cstring> #include<iostream> #include<queue> #define FOR(i,a,b) for(int i=a;i<=b;++i) #define clr(f,z) memset(f,z,sizeof(f)) using namespace std; const int mm=330; const int oo=0x3f3f3f3f; class Edge { public:int v,next,w; }; int g[mm][mm],n,m; class ShortPath { public: int head[mm],edge;Edge e[mm*mm*2]; void clear() { clr(head,-1);edge=0; } void add(int u,int v,int w) { e[edge].v=v;e[edge].w=w;e[edge].next=head[u];head[u]=edge++; } bool vis[mm];int id[mm]; void spfa(int s,int n,int*dis) { int u,v; FOR(i,0,n)dis[i]=oo,vis[i]=0; queue<int>Q; dis[s]=0;vis[s]=1;Q.push(s); while(!Q.empty()) { u=Q.front();Q.pop();vis[u]=0; for(int i=head[u];~i;i=e[i].next) { v=e[i].v; if(dis[v]>dis[u]+e[i].w) { dis[v]=dis[u]+e[i].w; if(!vis[v]) { Q.push(v); vis[v]=1;//++id[v];if(id[v]>=n)return -1; } } } } //return dis[n]; } }sf; int d1[mm],d2[mm]; int dp[mm][mm]; int DP(int x,int y) { if(dp[x][y]!=-1)return dp[x][y]; int ret=0; if(x==y)///equal point inc { ++ret; FOR(i,1,n) if(d1[i]+g[i][x]==d1[x]) FOR(j,1,n) if(d2[j]+g[j][y]==d2[y]) ret=max(ret,DP(i,j)+1); } FOR(i,1,n) if(d1[i]+g[i][x]==d1[x]) ret=max(ret,DP(i,y)); FOR(i,1,n) if(d2[i]+g[i][y]==d2[y]) ret=max(ret,DP(x,i)); dp[x][y]=ret; return ret; } int main() { int a,b,c,d; //freopen("data.in","r",stdin); while(~scanf("%d%d",&n,&m)) { if(n==0&&m==0)break; sf.clear(); FOR(i,0,n)FOR(j,0,n)g[i][j]=oo; FOR(i,1,m) {scanf("%d%d%d",&a,&b,&c);sf.add(a,b,c);sf.add(b,a,c); if(c<g[a][b]) g[a][b]=c,g[b][a]=c; } scanf("%d%d%d%d",&a,&b,&c,&d); sf.spfa(a,n,d1); sf.spfa(c,n,d2); FOR(i,0,n)FOR(j,0,n)dp[i][j]=-1; dp[a][c]=0; if(a==c)dp[a][c]=1; printf("%d\n",DP(b,d)); } }
以上是以前的代码 ,现在的代码 ,
#include <cstdio> #include <cstring> #include <queue> using namespace std; const int mm = 330; class Edge { public: int v,c,next; }e[mm*mm]; class ShortPath { public: int n,m; int head[mm],edge; int d[mm]; bool vis[mm]; Edge e[mm*mm*2]; void init() { memset(head,-1,sizeof(head)); edge = 0; } void add(int u,int v,int c) { e[edge].v = v; e[edge].c = c; e[edge].next = head[u]; head[u] = edge++; } void spfa(int s,int t) { int u,v; queue<int>Q; memset(vis,0,sizeof(vis)); memset(d,0x3f,sizeof(d)); Q.push(s); vis[s] = 1; d[s] = 0; while(!Q.empty()) { u = Q.front(); Q.pop(); vis[u] = false; for(int i=head[u];~i;i=e[i].next) { v = e[i].v; if(d[v] > d[u] + e[i].c) { d[v] = d[u] + e[i].c; if(!vis[v]) { Q.push(v); vis[v] = true; } } } } } }sp[2]; int dp[mm][mm]; int DP(int a,int b) { int u,v; if(dp[a][b] != -1) return dp[a][b]; for(int i=sp[0].head[a];~i;i=sp[0].e[i].next) { v = sp[0].e[i].v; u = a; if(sp[0].d[v] + sp[0].e[i].c != sp[0].d[u]) continue; if(v == b) dp[a][b] = max(DP(v,b)+1,dp[a][b]); else dp[a][b] = max(DP(v,b),dp[a][b]); } for(int i=sp[1].head[b];~i;i=sp[1].e[i].next) { v = sp[1].e[i].v; u = b; if(sp[1].d[v] + sp[1].e[i].c != sp[1].d[u]) continue; if(v == a) dp[a][b] = max(DP(a,v)+1,dp[a][b]); else dp[a][b] = max(DP(a,v),dp[a][b]); } dp[a][b] = max(dp[a][b],0); return dp[a][b]; } int main() { int a,b,c,n,m; while(~scanf("%d%d",&n,&m)) { if(n == 0 && m == 0) break; sp[0].n = sp[1].n = n; sp[0].m = sp[1].m = m; sp[0].init(); sp[1].init(); for(int i=0;i<m;++i) { scanf("%d%d%d",&a,&b,&c); sp[0].add(a,b,c); sp[0].add(b,a,c); sp[1].add(a,b,c); sp[1].add(b,a,c); } int u1,v1,u2,v2; scanf("%d%d%d%d",&u1,&v1,&u2,&v2); sp[0].spfa(u1,v1); sp[1].spfa(u2,v2); memset(dp,-1,sizeof(dp)); if(u1 == u2) dp[u1][u2] = 1; else dp[u1][u2] = 0; printf("%d\n",DP(v1,v2)); } return 0; }