首页 > 其他分享 >Codeforces Round #Pi (Div. 2) E. President and Roads (最短路+强连通求割边)

Codeforces Round #Pi (Div. 2) E. President and Roads (最短路+强连通求割边)

时间:2023-04-13 21:42:04浏览次数:53  
标签:cnt 求割边 int Codeforces edge MAXN Roads include head

题目地址:codeforces #pi (DIV2) E
题目很水。。就是先求两边最短路,然后把可能为最短路的边挑出来,然后判断是否yes只需要转化成无向图跑一遍tarjan,找出割边,割边就是yes,然后剩下的边就让它的值为最短路-1就行了,如果-1后变成了非正数,就是no.
但是!!!居然卡spfa!!那是不是说cf以后就不能用可以卡的算法了。。完全可以出组数据来卡这些算法。。。比如spfa,isap。。。
于是为了这题,又看了一遍迪杰斯特拉算法。。
代码如下:

#include <cstdio>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <cmath>
#include <map>
#include <stack>
#include <algorithm>
using namespace std ;
#pragma comment(linker, "/STACK:102400000,102400000")
#define LL __int64
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
const int MAXN=100000+10;
int head[MAXN], cnt, source, sink, vis[MAXN], ok[MAXN];
LL d[2][MAXN];
struct N
{
        int u, v;
        LL w;
}fei[MAXN];
struct node
{
        int u, v, next;
        LL w;
}edge[MAXN];
void add(int u, int v, LL w)
{
        edge[cnt].v=v;
        edge[cnt].w=w;
        edge[cnt].next=head[u];
        head[u]=cnt++;
}
void init(int n, int x)
{
        memset(head,-1,sizeof(head));
        cnt=0;
        for(int i=1;i<=n;i++){
                d[x][i]=(LL)1e15;
        }
}
struct Heap
{
        LL w;
        int id;
        Heap () {}
        Heap(LL w, int id): w(w),id(id) {}
        bool operator < (const Heap &a) const{
                return w>a.w;
        }
};
priority_queue<Heap>q;
void dijk(int x, int st)
{
        memset(vis,0,sizeof(vis));
        while(!q.empty()) q.pop();
        q.push(Heap(0,st));
        d[x][st]=0;
        while(!q.empty()){
                int u=q.top().id;
                q.pop();
                if(vis[u]) continue ;
                vis[u]=1;
                for(int i=head[u];i!=-1;i=edge[i].next){
                        int v=edge[i].v;
                        if(d[x][v]>d[x][u]+edge[i].w){
                                d[x][v]=d[x][u]+edge[i].w;
                                q.push(Heap(d[x][v],v));
                        }
                }
        }
}
int dfn[MAXN], low[MAXN], indx;
vector<pair<int,int> >G[MAXN];
void init1(int n)
{
        memset(dfn,0,sizeof(dfn));
        indx=0;
        memset(ok,0,sizeof(ok));
        for(int i=1;i<=n;i++){
                G[i].clear();
        }
}
void tarjan(int u, int fa)
{
        dfn[u]=low[u]=++indx;
        int flag=0;
        for(int i=0;i<G[u].size();i++){
                int v=G[u][i].first;
                if(v==fa&&!flag){
                        flag=1;
                        continue ;
                }
                if(!dfn[v]){
                        tarjan(v,u);
                        low[u]=min(low[u],low[v]);
                        if(dfn[u]<low[v]){
                                ok[G[u][i].second]=1;
                        }
                }
                else low[u]=min(low[u],dfn[v]);
        }
}
int main()
{
        int n, m, i, u, v, j;
        LL w;
        while(scanf("%d%d%d%d",&n,&m,&source,&sink)!=EOF){
                init(n,0);
                for(i=0;i<m;i++){
                        scanf("%d%d%I64d",&fei[i].u,&fei[i].v,&fei[i].w);
                        add(fei[i].u,fei[i].v,fei[i].w);
                }
                dijk(0,source);
                init(n,1);
                for(i=0;i<m;i++){
                        add(fei[i].v,fei[i].u,fei[i].w);
                }
                dijk(1,sink);
                init1(n);
                for(i=0;i<m;i++){
                        u=fei[i].u;
                        v=fei[i].v;
                        if(d[0][u]+d[1][v]+fei[i].w==d[0][sink]){
                                G[u].push_back(make_pair(v,i));
                                G[v].push_back(make_pair(u,i));
                        }
                }
                tarjan(source,-1);
                for(i=0;i<m;i++){
                        if(ok[i]){
                                puts("YES");
                                continue ;
                        }
                        u=fei[i].u;v=fei[i].v;
                        w=d[0][sink]-d[0][u]-d[1][v];
                        w--;
                        if(w<=0) puts("NO");
                        else printf("CAN %I64d\n",fei[i].w-w);
                }
        }
        return 0;
}

标签:cnt,求割边,int,Codeforces,edge,MAXN,Roads,include,head
From: https://blog.51cto.com/u_16070138/6188392

相关文章

  • Codeforces Round #305 (Div. 1) A.B.C 解题报告
    A.MikeandFrog枚举。先是找循环,然后很容易得出一个两元一次方程,然后可以发现解也是有循环节的,所以最小的那个肯定出现在一定范围内,否则就后面也不可能出现。假设两个变量为x,y,系数分别为z1,z2。很显然,两者的最小公倍数便是一个周期,所以如果枚举x的话,只需要枚举到z2就可......
  • codeforces#FF DIV2C题DZY Loves Sequences(DP)
    题目地址:http://codeforces.com/contest/447/problem/CC.DZYLovesSequencestimelimitpertestmemorylimitpertestinputoutputa,consistingof nai, ai + 1, .........
  • Codeforces Round #257 (Div. 1)B题Jzzhu and Cities(spfa+slf优化)
    题目地址:http://codeforces.com/contest/450/problem/D这题有重边,需要去重。。sad。当时居然没看见。。这题只要引入一个最短路条数,然后再遍历火车线,如果最短路与火车线长度相等,此时如果最短路条数是1的话,那说明这个最短路就是火车线,不能去掉,如果最短路条数大于1条,说明除了这条火车......
  • Educational Codeforces Round 146 (Rated for Div. 2)
    Preface补题ing值得一提的时补这场的时候先是遇上了CF的12小时大维护,后面又遇到了评测机崩了测不了也是有点有意思的说A.Coins傻逼题,首先考虑\(2|n\)时一定有解\(x=\frac{n}{2},y=0\),否则若\(2\nmidn\and2|k\)则由裴蜀定理知此时一定无解否则\(y\)必为奇数,我们令\(x=\fra......
  • Codeforces Round 864 (Div. 2)
    地址:cfround864赛后碎碎念,打的时候问题很多,就不一一列举了A.LiHuaandMaze怎么围得最少?你把一个点上下左右四个方向均放一个即可,但注意,边界处不需要放,之后对于两个点取小即可B.LiHuaandPattern怎么想?首先,遍历给定区域,判断给定取余还欠\(cnt\)个位置即可实现中心对称......
  • Codeforces Round 864 (Div. 2)
    Preface周六的最后一战,感觉脑子确实有点混沌了一个C题好多细节没考虑好心态差点爆炸最后还好20min速切了D稳了手排名,不然已经回到蓝名了感觉最近打比赛老是犯一些很离谱的失误,题目老是想不清楚导致好几场没法在比赛时写掉Div2的E了嘛说白了还是练得少了,多刷题解决一切问题的说......
  • UVa 11723 Numbering Roads (water ver.)
    11723-NumberingRoadsTimelimit:1.000secondshttp://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=2823Inmycountry,streetsdon’thavenames,eachofthemarejustgivenanumber......
  • Codeforces Round 862 (Div. 2)
    CodeforcesRound862(Div.2)Date:04/07/2023Link:Dashboard-CodeforcesRound862(Div.2)-CodeforcesA|WeNeedtheZeroBrief:给定非负整数序列,求一个\(x\),使得序列每个元素异或\(x\)后再全部异或起来的结果为\(0\).没有输出\(-1\).Data:\(T\leq1e3,......
  • Codeforces Round 864 (Div. 2) 题解
    A.LiHuaandMaze题目保证了两个点的哈密顿距离至少为\(2\),所以他们不会相邻。只要有点在角上答案就是\(2\),在边上但不在角上就是\(3\),否则就是\(4\)。#include<bits/stdc++.h>#include<ext/pb_ds/assoc_container.hpp>#include<ext/pb_ds/tree_policy.hpp>#includ......
  • Codeforces Round 864 (Div. 2)
    CodeforcesRound864(Div.2)题目链接CodeforcesRound864(Div.2)A题这个题是一个思维题稍微想一下应该就可以解决.1.我们可以发现如果点(x,y)位于正方形的四个角上把这个点围起来需要两次操作2.如果点(x,y)在正方形的4条边上,需要3个操作将其其围起来3.如果点(x,y)在......