Submission #6442064
Source Code Expand
#include <cstdio>
#include <algorithm>
#include <queue>
#include <utility>
#include <queue>
#include <vector>
#include <iostream>
#include <tuple>
using namespace std;
void chmax(int &A, int B) { A = max(A, B); }
// 移動元と行先と辺のコストを記録する構造体
template <typename T = int>
struct Edge {
int from, to;
T cost;
Edge(int s, T d = 1) : to(s), cost(d) {}
Edge(int f, int s, T d) : from(f), to(s), cost(d) {}
bool operator<(const Edge &e) const {
return cost < e.cost;
}
bool operator>(const Edge &e) const {
return cost > e.cost;
}
};
template <typename T = int>
using Graph = vector< vector< Edge<T> > >;
// 強連結成分分解
// Verified: AOJ GRL_3_C (Strongly Connected Components)
// Verified: ARC030 C (有向グラフ) ← 強連結を潰したグラフの構築の検証
// これは 2 回の DFS によって実現できる。
// はじめに普通の DFS をするが、その時に帰りがけ順に頂点番号の配列を作る。
// 次に、元のグラフの逆辺のみで構成されたグラフに対して、
// 帰りがけ順が遅かったものから順に DFS を行う。
// 帰りかけが遅かった頂点ほど、 DAG の先頭の強連結成分に属しているため、
// 辺を逆向きにすると、先頭の強連結成分から外に出られなくなることを利用している。
template <typename T = int>
struct GraphSCC {
public:
const int n;
vector<bool> isthrough;
vector<int> vs, cmp;
vector< vector<int> > G, rG, H; // グラフ、逆辺グラフ、縮約後のグラフ
GraphSCC(vector< vector< Edge<T> > > &g) :
n(g.size()), isthrough(n, false), cmp(n, 0), G(n), rG(n) {
for(int i=0; i<n; i++) {
for(size_t j=0; j<g[i].size(); j++) {
G[i].push_back(g[i][j].to);
rG[ g[i][j].to ].push_back(i);
}
}
}
void SCC_dfsone(int cur) {
isthrough[cur] = true;
for(size_t i=0; i<G[cur].size(); i++) {
if(!isthrough[G[cur][i]]) {
SCC_dfsone(G[cur][i]);
}
}
vs.push_back(cur);
}
void SCC_dfstwo(vector<int> &vec, int cur, int k) {
cmp[cur] = k;
isthrough[cur] = true;
vec.push_back(cur);
for(size_t i=0; i<rG[cur].size(); i++) {
if(!isthrough[rG[cur][i]]) {
SCC_dfstwo(vec, rG[cur][i], k);
}
}
}
// 縮約後のグループ、グループ数
pair<vector<int>, int> scc() {
// 1回めのDFS
for(int i=0; i<n; i++)
if(!isthrough[i]) SCC_dfsone(i);
fill(isthrough.begin(), isthrough.end(), false);
reverse(vs.begin(), vs.end());
int k = 0; vector< vector<int> > S;
// 2回めのDFS
for(size_t i=0; i<vs.size(); i++) {
if(!isthrough[vs[i]]) {
S.push_back(vector<int>());
SCC_dfstwo(S.back(), vs[i], k++);
}
}
H.resize(k);
fill(isthrough.begin(), isthrough.end(), false);
for(size_t i=0; i<k; i++) {
for(size_t j=0; j<S[i].size(); j++) {
int v = S[i][j];
for(size_t x=0; x<G[v].size(); x++) {
int u = G[v][x];
if(isthrough[cmp[u]] || cmp[v] == cmp[u]) continue;
isthrough[cmp[u]] = true;
H[cmp[v]].push_back(cmp[u]);
}
}
for(size_t j=0; j<H[i].size(); j++) isthrough[ H[i][j] ] = false;
}
return make_pair(cmp, k);
}
};
int main() {
int N; cin >> N;
Graph<> G(N);
for(int i=0; i<N; i++) {
for(int j=0; j<N; j++) {
int v; cin >> v;
if(v) G[i].emplace_back(j);
}
}
GraphSCC<> sc(G);
vector<int> cmp; int M;
tie(cmp, M) = sc.scc();
vector< vector<int> > adj(M+1, vector<int>(M+1));
vector< vector<int> > F(M+1);
vector<int> indeg(M+1);
for(int i=0; i<M; i++) {
F[M].emplace_back(i);
indeg[i]++;
adj[M][i] = true;
for(auto to : sc.H[i]) {
F[i].emplace_back(to);
indeg[to]++;
adj[i][to] = true;
}
}
/*
for(int i=0; i<=M; i++) {
for(int j=0; j<=M; j++) {
fprintf(stderr, "%d%c", adj[i][j], " \n"[j==M]);
}
}
*/
vector<int> topo, weight(M+1);
queue<int> que;
for(int i=0; i<N; i++) {
weight[ cmp[i] ]++;
}
for(int i=0; i<=M; i++) {
if(indeg[i] == 0) {
topo.emplace_back(i);
que.emplace(i);
}
}
while(que.size()) {
int cur = que.front(); que.pop();
for(auto to : F[cur]) {
if(--indeg[to] == 0) {
topo.emplace_back(to);
que.emplace(to);
}
}
}
vector< vector<int> > dp(M+1, vector<int>(M+1));
dp[0][0] = 0;
for(int i=0; i<=M; i++) {
for(int j=0; j<=M; j++) {
int u = topo[i], v = topo[j];
// i 側を進める
for(int k=i+1; k<=M; k++) {
int w = topo[k];
if(adj[u][w]) chmax(dp[k][j], dp[i][j] + weight[w]);
}
// j 側を進める
for(int k=i+1; k<=M; k++) {
int w = topo[k];
if(adj[u][w] or adj[v][w]) chmax(dp[k][i], dp[i][j] + weight[w]);
}
}
}
int ans = 0;
for(int i=0; i<=M; i++) for(int j=0; j<=M; j++) {
chmax(ans, dp[i][j]);
}
cout << ans << endl;
return 0;
}
Submission Info
Submission Time |
|
Task |
R - グラフ |
User |
tsutaj |
Language |
C++14 (GCC 5.4.1) |
Score |
0 |
Code Size |
5906 Byte |
Status |
WA |
Exec Time |
71 ms |
Memory |
1152 KB |
Judge Result
Set Name |
All |
Score / Max Score |
0 / 7 |
Status |
|
Set Name |
Test Cases |
All |
00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 90, 91 |
Case Name |
Status |
Exec Time |
Memory |
00 |
AC |
44 ms |
1024 KB |
01 |
WA |
45 ms |
1024 KB |
02 |
AC |
46 ms |
1024 KB |
03 |
WA |
44 ms |
1024 KB |
04 |
AC |
30 ms |
768 KB |
05 |
AC |
23 ms |
640 KB |
06 |
WA |
17 ms |
384 KB |
07 |
AC |
16 ms |
384 KB |
08 |
AC |
15 ms |
384 KB |
09 |
AC |
15 ms |
256 KB |
10 |
AC |
42 ms |
1024 KB |
11 |
WA |
48 ms |
1024 KB |
12 |
WA |
53 ms |
1024 KB |
13 |
AC |
57 ms |
1152 KB |
14 |
WA |
59 ms |
1152 KB |
15 |
WA |
63 ms |
1152 KB |
16 |
WA |
65 ms |
1152 KB |
17 |
WA |
67 ms |
1152 KB |
18 |
WA |
69 ms |
1152 KB |
19 |
WA |
71 ms |
1152 KB |
90 |
AC |
1 ms |
256 KB |
91 |
AC |
1 ms |
256 KB |