WuKong-HDU2833

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

题目: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]);


IFRS 9与CECL对比解析:跨国企业财务必须掌握的两种信用损失模型 本文深度解析IFRS 9与CECL两种信用损失模型的差异,帮助跨国企业应对财务合规挑战。从基础架构、数据治理到监管策略,详细对比三阶段模型与单一阶段模型的核心区别,并提供实施双轨制的实务建议,助力企业优化资本管理和税务筹划。 阅读详情

相关推荐

【可穿戴算法开发】-PPG信号检测方法

文章目录一、PPG(光电容积脉搏波法)信号的检测原理二.PPG技术目前存在的问题(挑战)三. **心电信号产生的原理** 随着经济的发展,在人们生活水平提高的同时,高脂肪摄入和低运动量成为了人们普遍的生活模式,近年来高血压、高血脂已经发展为危险性最高的病症。心电、血压、血氧等生理参数是预防和分析心血管疾病的重要生理参数。 常用的心电测量仪器有:多导ECG心电图仪、PPG心率检测器、心率带等; 常...

wxq_1993的博客 2万+

【记忆化搜索+图论】HDU-2833-WuKong

具体题解 题目 #include using namespace std; template T Max(T x,T y){return x>y?x:y;} template T Min(T x,T y){return x<y?x:y;} #define N 305 #define inf 999999999 int n,dis1[N],dis2[N],dp[N][N],map[N][N]

AndRing的专栏 839

应用软件——Altium Designer 19 Gerber/坐标文件

如何输出Gerber文件 步骤如下: 打开需要输出的PCB文件 2. 设置原点坐标 3. 打开Gerber Files 选项,File–>Fabrication Opuputs–>Gerber Files。 4. General参数设置。 用于指定输出Gerber文件中使用的单位(Units)和格式(Format)。单位可以是公制(Millimeters)和英制(Inches);格式栏中2:3,2:4,2:5代表文件中使用的不同数据精度,其中2:3表示数据含2位整数3位小数;相应的,另外两个分

染血黑兔的博客 7177

HDU2833 WuKong(floyd + dp)经典

WuKong Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1429    Accepted Submission(s): 517 Problem Description Liyuan wanted to rewrite

青山绿水之辈 专栏 1135

HDU2833 WuKong floyd+DP

传送门:【HDU2833 WuKong ti m

poursoul 809

hdu2833(2009多校第一场) 两条路最多交点

用floyd处理最短路的同时更新路上最多节点。 然后枚举重合线段,只要符合两条都是最短路即可更新ans。 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 int dis[315][315],num[315]...

weixin_33801856的博客 154

HDU 2833 最大流判满流

题意:n个人 #include #include #include #include #define INF 0x7fffffff #define M 550000 #define N 1005 using namespace std; int head[N],cnt,nv; struct edge{ int v,next,cap,flow; }e[M]; void i

AB 720

HDU 2833 WuKong

传送门 求两条最短路最多重叠的点数。 给一个无向图,再给两对起点终点,每一对起点终点之间都可能有多条最短的路,设s1和t1的最短路是r1,s2和t2的最短路是r2,求r1和r2最多能相互重叠多少个点。 这道题思想很巧妙,涉及了dp的思想。首先想明白一个问题,两条最短路的重叠部分必然是连续的,不可能有两段或更多段分散的重叠部分。为什么?反证法,若有的话,则某两段重叠部分之间的各自的分散部分一定可以都...

Crossing over 236

HDU 2833 WuKong(floyd最短路)

题目地址:HDU 2833 这题想到了最后是通过dis[s][t]==dis[s][i]+dis[i][j]+dis[j][t]的思路来判定是否属于最短路的一条。。但是没想到可以用floyd来找最短路中的点数。。。最短路还是太渣了。。好多性质都不会利用。。 这题的思路就是通过floyd对每两个点之间的最短路条数进行计数,然后通过上面的公式(对两条路线均要判定,都符合才说明都可以走),再找最短路

scf0920 1307

HDU 2833 WuKong 最短路

WuKong Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 208 Accepted Submission(s): 88   Problem Description Liyua

窦小雨的小点子 351

hdu2833 WuKong

给定两个起点终点,求两条最短路径上的最多交集点数。 求了最短路之后,枚举两条路上每条必然属于最短路径上的路径,(d[u]+w==d[v],则该条路径必然在最短路径上) dp[a][b]表示以a b为终点的最多交集点数。 #include #include #include #include #include #include #include #includ

Unknown 866

hdu 2833 WuKong

Dijkstra+记忆化搜索 首先用Dijkstra分别找到悟空和唐僧从起到终点的最短路径 最短路径的性质d[i] + edge[i][j] == d[j] 其中j为最短路径上的点,则i也为最短路径上的点。 由这个性质我们可以从终点逆向找到所有的最短路径上的点,做一遍记忆化搜索就可以得到结果。 #include #include #include using nam

tju_virus的专栏 562

hdu 2833 WuKong【floyd】

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2833 题意:悟空有一个起点终点,唐僧有一个起点终点,求他俩最短路径上最多 的交点个数。 分析:首先要知道它们的最多交点一定是一段连续的路径,因为如果不是连续的 则说明存在其他最短路段,都最短而最多交点不连续矛盾,我表达力不强不信就 试试。 然后可以用floyd跑全图的最短路,并且记录任意两

letterwuyu的专栏 762

HDU2833 WuKong Floyd

/* Floyd的应用 用Floyd求出任意两点间的最短路径 两个定理: 1.所求的路径一定是一断连续的路径 2.如果路径(x,y)是a->b的最短路径中的一段,则min(a,b) = min(a,x) + min(x,y) + min(y,b) 最后只需找到同时在两条最短路径上,且距离最长的那一段 */ #include using namespace std; const int inf=

幸福在路上 1405

HDU 2833——wukong

dijskra算法+搜索 首先分别求出悟空和唐僧各自的最短路径,然后记忆化搜索。 #include #include #include using namespace std; #define maxn 302 #define INF 10001 int map[maxn][maxn],dis1[maxn],dis2[maxn]; int dp[maxn][maxn]; void dij1(i

1120

DP WuKong hdu2833

挺好的一道题 想到对于任意两点(可相同),如果两路径都经过那么一定是走同样的两点之间的最短路 这道题就迎刃而解啦 代码如下: /* ^^ ====== ^^ ID: meixiuxiu PROG: test LANG: C++11 */ #include #include #include #include #include #include #include #incl

meixiuxiudd的博客 362

HDU-2833-WuKong

ACM模版描述题解很有趣的一道题……给定一个无向图,和两对起点终点,求两条最短路上的最多公共交点数。 可以dp+Floyd(代码One)搞搞,也可以dij+dfs(代码Two)搞搞,记忆化搜索,其实说白了都是dp。代码One:#include <iostream> #include <cstdio> #include <cstring> #include <algorithm>using name

逐梦者 569

HDU 2833 WuKong(floyd+dp)

题意:给你一张图,以及2对点,要求这2对点的最短路上最多能有多少点是共有的。 在做floyd的时候加上一个数组num来代表从i到j最短路最多能有几个点。 然后枚举i,j,如果i到j是起点a到终点b的最短路上的,那么dis[a][b] = dis[a][i]+dis[i][j]+dis[j][b],或者 dis[a][b] = dis[b][i]+dis[i][j]+dis[j][a] 然后这

glq007的acm的奋斗 548
上一篇: 线段树
下一篇: HDU-3768Shopping
After0514
博客等级 码龄12年 3粉丝 175原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值