• [国家集训队]稳定婚姻


    嘟嘟嘟

    这道题一看就知道是tarjan。

    刚开始我是建无向图,然后边双缩点,判断夫妻是否在一个边双连通分量中。但是这个算法是错的,我也不知道为啥,求助各路大佬。

    正确的做法是给每一条边规定方向:夫妻边女->男,情侣边男->女。这样就保证了每一条路径一定是男->女->男->女。最后只用判断每一对夫妻是否在一个环中,即是否在一个强联通分量中。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cmath>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<cctype>
      8 #include<vector>
      9 #include<queue>
     10 #include<stack>
     11 #include<map>
     12 using namespace std;
     13 #define enter puts("")
     14 #define space putchar(' ')
     15 #define Mem(a, x) memset(a, x, sizeof(a))
     16 #define rg register
     17 typedef long long ll;
     18 typedef double db;
     19 const db eps = 1e-8;
     20 const int INF = 0x3f3f3f3f;
     21 const int maxn = 8e3 + 5;
     22 const int maxe = 4e4 + 5;
     23 inline ll read()
     24 {
     25     ll ans = 0;
     26     char ch = getchar(), las = ' ';
     27     while(!isdigit(ch)) las = ch, ch = getchar();
     28     while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
     29     if(las == '-') ans = -ans;
     30     return ans;
     31 }
     32 inline void write(ll x)
     33 {
     34     if(x < 0) putchar('-'), x = -x;
     35     if(x >= 10) write(x / 10);
     36     putchar(x % 10 + '0');
     37 }
     38 
     39 int n, m;
     40 char c[10];
     41 map<string, int> mp;
     42 int Cnt = 0;
     43 struct Edges
     44 {
     45     int x, y;
     46 }egs[maxe];
     47 struct Edge
     48 {
     49     int nxt, to;
     50 }e[maxe << 1];
     51 int head[maxn], ecnt = -1;
     52 void addEdge(int x, int y)
     53 {
     54     e[++ecnt] = (Edge){head[x], y};
     55     head[x] = ecnt;
     56 }
     57 
     58 int st[maxn], top = 0;
     59 int dfn[maxn], low[maxn], cnt = 0;
     60 bool in[maxn];
     61 int col[maxn], ccol = 0;
     62 void tarjan(int now)
     63 {
     64     dfn[now] = low[now] = ++cnt;
     65     st[++top] = now; in[now] = 1;
     66     for(int i = head[now]; i != -1; i = e[i].nxt)
     67     {
     68         if(!dfn[e[i].to])
     69         {
     70             tarjan(e[i].to);
     71             low[now] = min(low[now], low[e[i].to]);
     72         }
     73         else if(in[e[i].to]) low[now] = min(low[now], dfn[e[i].to]);
     74     }
     75     if(dfn[now] == low[now])
     76     {
     77         int x; ++ccol;
     78         do
     79         {
     80             x = st[top--];
     81             col[x] = ccol;
     82             in[x] = 0;
     83         }while(x != now);
     84     }
     85 }
     86 
     87 int main()
     88 {
     89     Mem(head, -1);
     90     n = read();
     91     for(int i = 1; i <= n; ++i)
     92     {
     93         int x, y;
     94         scanf("%s", c);
     95         if(!mp[c]) mp[c] = ++Cnt;
     96         x = mp[c];
     97         scanf("%s", c);
     98         if(!mp[c]) mp[c] = ++Cnt;
     99         y = mp[c];
    100         addEdge(x, y);
    101         egs[i].x = x; egs[i].y = y;
    102     }
    103     m = read(); 
    104     for(int i = 1; i <= m; ++i)
    105     {
    106         scanf("%s", c); int x = mp[c];
    107         scanf("%s", c); int y = mp[c];
    108         addEdge(y, x);
    109     }
    110     for(int i = 1; i <= Cnt; ++i) if(!dfn[i]) tarjan(i);
    111     for(int i = 1; i <= n; ++i)
    112     {
    113         if(col[egs[i].x] == col[egs[i].y]) puts("Unsafe");
    114         else puts("Safe");
    115     }
    116     return 0;
    117 }
    View Code
  • 相关阅读:
    企业级应用TOMCAT
    HTTP服务及状态码
    Zabbix服务网页报错汇总
    spring aop 嵌套方法注解不生效
    oracle数据库密码修改和解锁
    redis安装
    docker简介
    ffmpeg简介
    JAVA学习笔记之变量
    JAVA学习笔记之类和对象
  • 原文地址:https://www.cnblogs.com/mrclr/p/9861056.html
Copyright © 2020-2023  润新知