图论考查的总结(2)

一.P1982 团伙

1.本题依旧是紧张刺激的并查集(>-<),原理是用树维护集合,树根编号为集合编号。

    int find(int x){
            if(f[x]!=x) f[x]=find(f[x]);
            return f[x];
   }

2.Friend合并,Enemy记录,再把下一个Enemy和记录的Enemy合并。因为敌人的敌人是朋友。比如 E 1 2, E 2 3,记录E[1] = 2, E[2] = 1现在到了E 2 3,E[2]有了,那么把1,3合并,然后记录E[3] = 2。由于敌人的敌人已经合并,那么这时的1或者3都是2的敌人,取一个代表就行,下次再碰到2和某个人是敌人,把他和1合并或把它和3合并是一样的。连通块在合并的时候统计就可以了。

3.         (1)对于两个人之间的关系,可以不存在关系,记录下不能合并的关系,再次找到时合并可以合并的人

            (2)对于两个人之间的关系,一定存在关系,用带权并査集

        void un(int x,int y){
                if(find(x)!=find(y)){
                res--;
                f[find(x)]=find(y);
                }
       }

    for(int i=1;i<=n;i++) f[i]=i;
    res=n;
    for(int i=1;i<=m;i++){
        char op[10];
        int x, y;
        scanf("%s%d%d",op,&x,&y);
        if(op[0]=='F') un(x,y);
        else{
            if(e[y]) un(x,e[y]);
            else e[y] = x;
            if(e[x]) un(y,e[x]);
            else e[x]=y;
        }
    }
    printf("%d", res);

二.P1491 集合位置

1.这是次短路问题(很明显吧)顾名思义,就是仅次于图中最短路的最短的路。

2.采用删边的思想,先跑一遍最短路并记录下来。

   然后依次删去最短路径上每一条边,分别跑一遍最短路,取所有答案中的最小值。

(不去掉最短路上的边,最短路没有变化)

3.在跑第一遍最短路的时候记录被更新的点的前驱,(只有第一次跑,才要记录路径)

4.本题没有负边权,建议Dijkstra+堆优化(注意数据类型是double)

PS:思路不顺望见谅

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值