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
原创粉丝点击