HDU-6370
Posted lordxx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU-6370相关的知识,希望对你有一定的参考价值。
tarjan找环。我们通过枚举一个点的入边为wolf/village出边为wolf/village ,可以知道,当且仅当,一个环里面有且仅有一个出边为wolf的时候,被指向的那个人为wolf。
一旦能够确定wolf了,那么所有指向wolf的人,如果出边为village,那么这个人也是wolf。反向dfs即可。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#pragma GCC optimize(2)
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
char ch = getchar(); ll x = 0, f = 1;
while (ch<‘0‘ || ch>‘9‘) { if (ch == ‘-‘)f = -1; ch = getchar(); }
while (ch >= ‘0‘ && ch <= ‘9‘) { x = x * 10 + ch - ‘0‘; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 1e5 + 10;
struct eg{
int v, wi, next;
}out[N], in[N];
int head_out[N], head_in[N];
struct tt {
int u, v, wi;
};
stack<int>st;
int dfn[N], low[N];
eg to[N];
int vis[N];
int now, ans;
int cnt1, cnt2;
int scc_cnt = 0;
vector<int>block[N];
void addedge(int u, int v, int wi)
{
out[cnt1].v = v;
out[cnt1].wi = wi;
out[cnt1].next = head_out[u];
to[u] = eg{ v,wi };
head_out[u] = cnt1++;
in[cnt2].v = u;
in[cnt2].wi = wi;
in[cnt2].next = head_in[v];
head_in[v] = cnt2++;
}
int tot;
void tarjan(int u)
{
dfn[u] = low[u] = ++tot;
vis[u] = 1;
st.push(u);
int v = to[u].v;
int temp_w = to[u].wi;
if (!dfn[v])
{
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if(vis[v])
{
low[u] = min(low[u],dfn[v]);
}
// vis[u] = 0;
if (dfn[u] == low[u])
{
scc_cnt++;
int cur;
do
{
cur = st.top(); st.pop();
vis[cur] = 0;
block[scc_cnt].push_back(cur);
} while (cur!= u);
}
}
void dfs(int u)
{
for (int i=head_in[u];~i;i=in[i].next)
{
int v = in[i].v;
int temp_wi = in[i].wi;
if (temp_wi == 0)
{
ans++;
dfs(v);
}
}
}
int n, T;
int main()
{
T = read();
while (T--)
{
n = read();
upd(i, 0, n)low[i] = dfn[i] = 0;
tot = 0;
cnt1 = cnt2 = 0; scc_cnt = 0;
while(!st.empty())st.pop();
memset(head_out, -1, sizeof(head_out));
memset(head_in, -1, sizeof(head_in));
ans = 0;
char s[10];
int v, w;
upd(i, 1, n)
{
v = read(); scanf("%s", s);
if(s[0]==‘w‘)
addedge(i, v, 1);
else addedge(i, v, 0);
}
upd(i, 1, n)
{
if (!dfn[i])
{
tarjan(i);
}
}
upd(i, 1, scc_cnt)
{
if (block[i].size() == 1)continue;
int temp_num = 0;
for (auto tp : block[i])
{
int v = to[tp].v;
int w = to[tp].wi;
if (w == 1) { temp_num++; now = v; }
}
if (temp_num == 1)
{
ans++;
dfs(now);
}
}
upd(i, 0, scc_cnt)block[i].clear();
printf("%d %d
", 0, ans);
}
}
以上是关于HDU-6370的主要内容,如果未能解决你的问题,请参考以下文章
HDU - 6370 Werewolf 2018 Multi-University Training Contest 6 (DFS找环)