WuKong-HDU2833
来源:互联网 发布:linux close函数 编辑:程序博客网 时间:2024/05/21 11:34
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2833
题意:给定无向图,求两条最短路A->B,C->D,问这两条最短路的公共点最多有多少个
思路:1:floyd预处理所有点对最短路:
2:记忆化搜索:
首先A->B的最短路径,可以形成一棵有根树,
沿着A->B的最短路径形成的树,从A开始搜索,
dp[u],表示从u->B,两条最短路的最多公共定点数
if(edge(u->v)在A->B和C->D最短路径树上)dp[u]=max(dp[u],dp[v]+1);
else dp[u]=max(dp[u],dp[v]);
#include<cstdio>#include<iostream>#include<cstring>using namespace std;const int N=310;const int M=310*310*2;const int INF=1<<30;int map[N][N];int dp[N];int vis[N];inline int min(int a,int b){ return a<b?a:b;}inline int max(int a,int b){ return a>b?a:b;}struct Edge{ int to,next,w;}e[M];int total,head[N];void add_edges(int from,int to,int w){ e[total].to=to,e[total].next=head[from],e[total].w=w,head[from]=total++;}void init(){ total=0;memset(head,-1,sizeof(head));}void floyd(int n){ for(int k=0;k<n;k++) { for(int i=0;i<n;i++) { if(map[i][k]==INF)continue; for(int j=0;j<n;j++) { if(map[k][j]==INF)continue; map[i][j]=min(map[i][j],map[i][k]+map[k][j]); } } }}int s1,t1,s2,t2;inline int f(int u){ if(map[s2][u]==INF||map[u][t2]==INF||map[s2][t2]!=map[s2][u]+map[u][t2])return 0; return 1;}void dfs(int u){ int ans=0; vis[u]=1; int cnt=0; int flag=f(u); if(u==t1) { dp[u]=flag; return ; } for(int i=head[u];i!=-1;i=e[i].next) { int v=e[i].to; if(map[v][t1]==INF)continue; if(map[u][t1]==map[v][t1]+e[i].w) { if(flag&&((map[u][t2]==map[v][t2]+e[i].w)||u==t2))cnt=1; else cnt=0; if(vis[v]) { ans=max(ans,dp[v]+cnt); } else { dfs(v); ans=max(ans,dp[v]+cnt); } } } if(!ans&&flag)ans=1;////表示u是第一个公共点 dp[u]=ans;}int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF,n||m) { init(); for(int i=0;i<n;i++) { map[i][i]=0; for(int j=i+1;j<n;j++) { map[i][j]=map[j][i]=INF; } } for(int i=0;i<m;i++) { int a,b,c;scanf("%d%d%d",&a,&b,&c);a--;b--; add_edges(a,b,c);add_edges(b,a,c); map[a][b]=map[b][a]=min(map[a][b],c); } floyd(n); memset(vis,0,sizeof(vis)); scanf("%d%d%d%d",&s1,&t1,&s2,&t2);s1--;t1--;s2--;t2--; /*for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { printf("%d,",map[i][j]); }printf("\n"); }*/ if(map[s1][t1]==INF||map[s2][t2]==INF) { //printf("line1\n"); printf("0\n");continue; } dfs(s1); //for(int i=0;i<n;i++){printf("%d--%d,",i+1,dp[i]);} printf("%d\n",dp[s1]); } return 0;}
p[v]);
0 0
- hdu2833 WuKong
- WuKong-HDU2833
- HDU2833 WuKong Floyd
- DP WuKong hdu2833
- HDU2833:WuKong(Floyd 最大共同公共点)
- HDU2833 WuKong(floyd + dp)经典
- hdu2833
- HDU2388 WuKong
- hdu2833 Floyd + dp
- HDU2833-最短路+dp
- hdu 2833 WuKong
- hdu 2833 WuKong
- 复习图--WuKong
- HDU 2833 WuKong
- hdu 2833 WuKong【floyd】
- 【HDU 2833】WuKong 【Floyd】
- HDU-2833-WuKong
- HDU 2833 WuKong
- 内部类
- Mongodb
- GitHub 配置及简单使用
- 欢迎使用CSDN-markdown编辑器
- Redis
- WuKong-HDU2833
- fleury 算法模版
- 如何学习Cocos2d-X
- 一个bitmap缓存的工具类
- 【Android 笔记】OnScrollListener详解
- 神奇的android:clipChildren属性
- 初识qemu
- java实现排序的几种方法
- git clone检出项目慢