POI2012FES-Festival

xiaruize發表於2024-04-25

POI #Year2012 #Tarjan #最短路

強聯通分量之間是不影響的,考慮對於一個強聯通分量內,方案數等於這個強聯通內的最短路\(+1\)

// Author: xiaruize
const int N = 6e2 + 10;

int n, m1, m2;
vector<int> g[N];
int dis[N][N];
bool vis[N];
int dfn[N], top[N], low[N], tot;
stack<int> st;
int res[N];
int id[N], cnt = 0;

void tarjan(int x)
{
	dfn[x] = low[x] = ++tot;
	st.push(x);
	vis[x] = true;
	for (auto v : g[x])
	{
		if (!dfn[v])
		{
			tarjan(v);
			low[x] = min(low[x], low[v]);
		}
		else if (vis[v])
		{
			low[x] = min(low[x], dfn[v]);
		}
	}
	if (dfn[x] == low[x])
	{
		cnt++;
		while (st.top() != x)
		{
			id[st.top()] = cnt;
			vis[st.top()] = false;
			st.pop();
		}
		id[st.top()] = cnt;
		vis[st.top()] = false;
		st.pop();
	}
}

void solve()
{
	mms(dis, 0x3f);
	cin >> n >> m1 >> m2;
	rep(i, 1, m1)
	{
		int u, v;
		cin >> u >> v;
		dis[u][v] = min(dis[u][v], 1);
		dis[v][u] = min(dis[v][u], -1);
		g[u].push_back(v);
		g[v].push_back(u);
	}
	rep(i, 1, m2)
	{
		int u, v;
		cin >> u >> v;
		dis[v][u] = min(dis[v][u], 0);
		g[v].push_back(u);
	}
	rep(i, 1, n)
	{
		dis[i][i] = 0;
		if (!dfn[i])
			tarjan(i);
	}
	rep(k, 1, n)
	{
		rep(i, 1, n)
		{
			if (id[k] != id[i] && dis[i][k] < INF)
				continue;
			rep(j, 1, n)
			{
				dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
			}
		}
	}
	rep(i, 1, n)
	{
		if (dis[i][i] < 0)
		{
			cout << "NIE" << endl;
			return;
		}
		rep(j, 1, n) if (id[i] == id[j])
			res[id[i]] = max(res[id[i]], dis[i][j] + 1);
	}
	int ans = 0;
	rep(i, 1, n) ans += res[i];
	cout << ans << endl;
}

#ifndef ONLINE_JUDGE
bool end_of_memory_use;
#endif

signed main()
{
	// freopen(".in","r",stdin);
	// freopen(".out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int testcase = 1;
	// cin >> testcase;
	while (testcase--)
		solve();
#ifndef ONLINE_JUDGE
	cerr << "Memory use:" << (&end_of_memory_use - &start_of_memory_use) / 1024.0 / 1024.0 << "MiB" << endl;
	cerr << "Time use:" << (double)clock() / CLOCKS_PER_SEC * 1000.0 << "ms" << endl;
#endif
	return 0;
}