【Educational Codeforces Round 10E】【双连通分量缩环 BFS】Pursuit For Artifacts ★

来源:互联网 发布:安装win7无法连接网络 编辑:程序博客网 时间:2024/06/01 19:31
【trick&&吐槽】
1,缩环重建图的时候一定要注意映射关系。

【题意】
有n(3e5)个点,m(3e5)条双向边(xi,yi,zi)。
没有重边没有自环(这个条件其实无所谓)
有些边是特殊的边(zi==1)
每条边只能经过一次
问你我们能否有一条路径,使得我们可以从ST出发到达ED

【类型】
双连通分量tarjan缩环
BFS

【分析】
这题思考起来有些不着边际。
关键信息是——一条边只能经过一次。
什么情况下一条边我们会经过多次呢?
经过多次必然形成了环。
于是,介于这个图是无向图,我们可以考虑先双连通缩环。
如果ST和ED在同一个联通块内,且这个联通块内有special edge 显然答案为YES
否则的话,已经缩环之后的图,ST与ED之前肯定只有单一路径可达,每个点只会入栈一次,被更新一次,于是直接做BFS即可。

就AC啦!

#include <map>#include <stack>#include <queue>#include <deque>#include <cmath>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF  0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-12#define maxn 300100#define MOD 1000000007struct Edge{    int to,next,val;} edge[maxn<<1];int n,m;int tot,head[maxn],scc;int dfn[maxn],low[maxn],time;int sta[maxn],top,S,E,instack[maxn];int belong[maxn],tmp[maxn];vector<pair<int,int> > a[maxn];void init(){    tot = 0;    memset(head,-1,sizeof(head));}void add_edge(int u,int v,int cnt){    edge[tot].to = v;    edge[tot].val = cnt;    edge[tot].next = head[u];    head[u] = tot++;}void tarjan(int u,int pre){    dfn[u] = low[u] = time++;    sta[++top] = u;    instack[u] = 1;    for(int i = head[u]; i != -1; i = edge[i].next)    {        int v = edge[i].to;        if(v == pre)                   continue;        if(!dfn[v])               {                             tarjan(v,u);                               low[u] = min(low[u],low[v]);        }               else if(instack[v])                       low[u] = min(low[u],dfn[v]);               }     if(dfn[u] == low[u])       {                       tmp[++scc] = 0;                       a[scc].clear();                       while(1)               {                                   int v = sta[top--];                                   instack[v] = 0;                                   belong[v] = scc;            if(v == u)                               break;                           }       }}int bfs(){    memset(instack,0,sizeof(instack));    queue<int> q;    q.push(belong[S]);    instack[belong[S]] = 1;    while(!q.empty())       {                       int u = q.front();                       q.pop();        for(int i = a[u].size() - 1; i >= 0; i--)               {                                   int v = a[u][i].first;                                   int tp = a[u][i].second;            if(instack[v])                               continue;            tmp[v] |= tmp[u];            tmp[v] |= tp;            q.push(v);            instack[v] = 1;        }       }       return tmp[belong[E]];}int solve(){           for(int u = 1; u <= n; u++)               for(int i = head[u]; i != -1; i = edge[i].next)               {                                   int v = edge[i].to;                                 if(belong[u] == belong[v])                               tmp[belong[u]] |= edge[i].val;                                 a[belong[u]].push_back(make_pair(belong[v],edge[i].val));                           }       if(belong[S] == belong[E] && tmp[belong[S]])               return 1;    return bfs();}int main(){    int t;    while(scanf("%d%d",&n,&m) != EOF)       {                       init();                       for(int i = 0; i < m; i++)               {                                   int x,y,z;            scanf("%d%d%d",&x,&y,&z);                                   add_edge(x,y,z);            add_edge(y,x,z);            scanf("%d%d",&S,&E);            top = 0;            time = scc = 0;            memset(dfn,0,sizeof(dfn));            memset(instack,0,sizeof(instack));            tarjan(1,0);            printf("%s\n",solve()?"YES":"NO");        }    }       return 0;}

0 0
原创粉丝点击