首页 > 其他分享 >POI2006PRO-Professor Szu

POI2006PRO-Professor Szu

时间:2024-04-15 19:44:23浏览次数:23  
标签:cnt int Professor POI2006PRO st Szu col dp define

缩点 #dp #POI #Year2006

建反图, \(tarjan\) 缩点,在有向无环图上跑 \(topsort\),\(dp\) 计算方案数

超过 \(36500\) 的直接与 \(36501\) 取 \(min\) 就可以避免炸 \(long\ long\)

特判

  • 最大方案数为从最后一个点的强联通出发
  • 最后一个点有自环
```cpp
// Author: xiaruize
#ifndef ONLINE_JUDGE
#define debug(x) cerr << "On Line:" << __LINE__ << #x << "=" << x << endl
bool start_of_memory_use;
#else
#define debug(x)
#endif
#include <bits/stdc++.h>
using namespace std;
#ifndef ONLINE_JUDGE
clock_t start_clock = clock();
#endif
#define int long long
#define ull unsigned long long
#define ALL(a) (a).begin(), (a).end()
#define pb push_back
#define mk make_pair
#define pii pair<int, int>
#define pis pair<int, string>
#define sec second
#define fir first
#define sz(a) int((a).size())
#define Yes cout << "Yes" << endl
#define YES cout << "YES" << endl
#define No cout << "No" << endl
#define NO cout << "NO" << endl
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define rep(i, a, n) for (int i = (a); i <= (n); ++i)
#define per(i, n, a) for (int i = (n); i >= (a); --i)
int max(int a, int b)

{
	if (a > b)
		return a;
	return b;
}
int min(int a, int b)
{
	if (a < b)
		return a;
	return b;
}
const int INF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1000000007;
const int N = 1e6 + 10;

int n, m;
vector<int> g[N], f[N];
pii eg[N];
int dfn[N], low[N], siz[N];
int col[N], tot, cnt;
stack<int> st;
bool vis[N];
bool sta[N];
int deg[N], dp[N];

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 (low[x] == dfn[x])
	{
		cnt++;
		while (st.top() != x)
		{
			col[st.top()] = cnt;
			vis[st.top()] = false;
			siz[cnt]++;
			st.pop();
		}
		siz[cnt]++;
		vis[st.top()] = false;
		col[st.top()] = cnt;
		st.pop();
	}
}

void solve()
{
	cin >> n >> m;
	n++;
	rep(i, 1, m)
	{
		cin >> eg[i].first >> eg[i].second;
		g[eg[i].second].push_back(eg[i].first);
	}
	rep(i, 1, n) if (!dfn[i]) tarjan(i);
	rep(i, 1, m)
	{
		auto [u, v] = eg[i];
		if (col[u] == col[v])
			sta[col[u]] = true;
		else
		{
			f[col[v]].push_back(col[u]);
			deg[col[u]]++;
		}
	}
	queue<int> q;
	rep(i, 1, cnt) if (!deg[i]) q.push(i);
	while (!q.empty())
	{
		int x = q.front();
		q.pop();
		if (x == col[n])
			continue;
		for (auto v : f[x])
		{
			deg[v]--;
			if (!deg[v])
				q.push(v);
		}
	}
	q.push(col[n]);
	dp[col[n]] = 1;
	while (!q.empty())
	{
		auto x = q.front();
		q.pop();
		if (sta[x])
			dp[x] = 36501;
		for (auto v : f[x])
		{
			deg[v]--;
			dp[v] += dp[x];
			dp[v] = min(dp[v], 36501);
			if (!deg[v])
				q.push(v);
		}
	}
	int mx = 0;
	rep(i, 1, cnt)
	{
		mx = max(mx, dp[i]);
	}
	if (mx > 36500)
		cout << "zawsze" << endl;
	else
		cout << mx << endl;
	int res = 0;
	rep(i, 1, cnt) if (dp[i] == mx) res += siz[i];
	cout << res - (mx == dp[col[n]]) << endl;
	rep(i, 1, n - 1)
	{
		if (dp[col[i]] == mx)
			cout << i << ' ';
	}
	cout << 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;
}

标签:cnt,int,Professor,POI2006PRO,st,Szu,col,dp,define
From: https://www.cnblogs.com/xiaruize/p/18136791

相关文章

  • 【SZU计算机网络实验】实现流式视频传输
    前言一百年没有更新博客了,都怪开学一堆杂活(x那就顺手把实验报告转到这边吧owo本实验为SZU原创实验,实验开发团队的老师和助教们都很有耐心。。大赞,环境没配好去群里问是秒回的相关资料:实验文档:计算机网络课程综合实验平台(snrc.site)一、实验介绍该实验主要实现了一......
  • CF1705E Mark and Professor Koro 题解
    题意:给定一个长度为$n$$(1\len\le2e5)$的序列,每次可以把两个相等的$a_i$和$a_j$合并为一个$a_i+1$。给定$q$$(1\leq\le2e5)$次修改,每次将$a_k$修改为$l$,求每次操作后合并到无法再合并时出现的最大数。其中,$1\lea_i\le2e5$。......
  • CF70D Professor's task 题解 & 动态凸包板子
    CF70DProfessor'stask题解前言此篇题解用的是\(Andrew\),不想看这种做法的可以绕道。题意动态凸包板子题。维护动态凸包。两种操作,加一个点或查询一个点是否在凸包内。题解首先你得会静态二维凸包。维护二维凸包的方法挺多的,比如什么\(Andrew\)算法,\(Jarvis\)算法还......
  • Codeforces 70D. Professor's task
    题目链接:D-Professor'stask题目大意:初始给三个点,之后要求实现两种操作:加点;判断给定点是否在凸包内部。动态凸包板子题,留档怕忘了,参考https://www.cnblogs.com/enzymi......
  • computer professor --
                         ......
  • 2022-SZUACM招新 训练赛2
    2022-SZUACM招新训练赛2https://vjudge.net/contest/544906#overview下午打了一下,稍微记录一波,有一些蛮有意思的小题。A-Arrayhttps://codeforces.com/problemset/p......
  • Professor Maitland Jones Jr. was dismissed from NYU
    https://archive.ph/FDy23Nowapieceofunsolicitedadvice:Itisverydifficulttobeself-critical.Itishardtoacceptpersonalresponsibilitywhenwemee......
  • [POI2006]Pro-Professor Szu & ZLOJ 练习62 B
    writtenon2022-08-09题目不难,但是需要总结一下。题意很明确,就不过多阐述了。读完题目后,很明显可以建反图,然后就会有两种方法。第一种方法是直接拓扑排序找环,这种方式......