답안 #942785

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
942785 2024-03-11T04:42:29 Z pan 연결리스트 수사하기 (NOI12_forensic) C++17
25 / 25
87 ms 1324 KB
#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//#include "bits_stdc++.h"
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define lb lower_bound
#define ub upper_bound
#define input(x) scanf("%lld", &x);
#define input2(x, y) scanf("%lld%lld", &x, &y);
#define input3(x, y, z) scanf("%lld%lld%lld", &x, &y, &z);
#define input4(x, y, z, a) scanf("%lld%lld%lld%lld", &x, &y, &z, &a);
#define print(x, y) printf("%lld%c", x, y);
#define show(x) cerr << #x << " is " << x << endl;
#define show2(x,y) cerr << #x << " is " << x << " " << #y << " is " << y << endl;
#define show3(x,y,z) cerr << #x << " is " << x << " " << #y << " is " << y << " " << #z << " is " << z << endl;
#define discretize(x) sort(x.begin(), x.end()); x.erase(unique(x.begin(), x.end()), x.end());
using namespace std;
//using namespace __gnu_pbds;
//#define ordered_set tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
//#define ordered_multiset tree<int, null_type, less_equal<int>, srb_tree_tag, tree_order_statistics_node_update>
typedef long long ll;
typedef long double ld;
typedef pair<ld, ll> pd;
typedef pair<string, ll> psl;
typedef pair<ll, ll> pi;
typedef pair<pi, ll> piii;
typedef pair<pi, pi> pii;

// IDEA:
// link list can be modelled as a tree with strictly 1 parent but sometime got loop
// longest chain must start from 0
// ans = 0 chain + 1 other longest sub chain
// dfs1 will kil the first, second need to consider cases 
// Connecting tail of 0 chain to its child is always invalid (create loop)
// Connecting 0 chain to other branch from node along 0 chain is ok (dp[u] =0 as u and all ts parent is already counted in 0 chain)
// But connecting to node in 0 chain cann't make it any longer (dp[u] =0)
// If 0 is a part of cycle, other branch in that connected component is invalid as sub-chain (need at least 2 op to break loop)
// Then other normal tree w/o loop is valid, do dfs2 to complete search for this
ll const INF = 1e13;
ll n;
bool loop = false;
ll chain0 = 0, another = 0;
ll dp[20005];
ll par[20005];
bool visited[20005], status[20005];
void dfs1(ll from)
{
	visited[from] = 1;
	dp[from] = 0;
	chain0++;
	if (par[from]==-1) return;
	if (visited[par[from]]) {loop = true; return;}
	dfs1(par[from]);
}

ll dfs2(ll from)
{
	//show2(from, status[from]);
	if (from==-1) return 0;
	ll nxt = par[from];
	if ((loop && visited[nxt]) || nxt==0) return -INF; // last two invalid cases
	//show(1);
	if (dp[from]!=-1) return dp[from]; // already calculated
	if (status[from]==1) return -INF; // found another loop outside 0 chain, invalid
	status[from] = 1;
	//show(1);
	dp[from] = dfs2(nxt)+1;
	show(dp[from]);
	status[from] = 2;
	return dp[from];
}

int main()
{
	ll n;
	input(n);
	fill(visited, visited+n, 0);
	fill(status, status+n, 0);
	fill(dp, dp+n, -1);
	for (ll i=0; i<n; ++i)  input(par[i]);
	dfs1(0);
	for (ll i=0; i<n; ++i) if (!visited[i]) { another =max(another, dfs2(i));}
	print(chain0 + another, '\n');
	return 0;
}

Compilation message

forensic.cpp: In function 'int main()':
forensic.cpp:11:23: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   11 | #define input(x) scanf("%lld", &x);
      |                  ~~~~~^~~~~~~~~~~~
forensic.cpp:79:2: note: in expansion of macro 'input'
   79 |  input(n);
      |  ^~~~~
forensic.cpp:11:23: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   11 | #define input(x) scanf("%lld", &x);
      |                  ~~~~~^~~~~~~~~~~~
forensic.cpp:83:26: note: in expansion of macro 'input'
   83 |  for (ll i=0; i<n; ++i)  input(par[i]);
      |                          ^~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 348 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 0 ms 348 KB Output is correct
4 Correct 0 ms 348 KB Output is correct
5 Correct 0 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 348 KB Output is correct
2 Correct 9 ms 344 KB Output is correct
3 Correct 13 ms 348 KB Output is correct
4 Correct 9 ms 348 KB Output is correct
5 Correct 13 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 7 ms 344 KB Output is correct
2 Correct 1 ms 344 KB Output is correct
3 Correct 1 ms 344 KB Output is correct
4 Correct 3 ms 348 KB Output is correct
5 Correct 9 ms 604 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 712 KB Output is correct
2 Correct 45 ms 1324 KB Output is correct
3 Correct 87 ms 1108 KB Output is correct
4 Correct 2 ms 856 KB Output is correct
5 Correct 14 ms 600 KB Output is correct