이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#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;
}
컴파일 시 표준 에러 (stderr) 메시지
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]);
| ^~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |