結果
| 問題 |
No.1813 Magical Stones
|
| コンテスト | |
| ユーザー |
👑 |
| 提出日時 | 2021-12-29 15:22:46 |
| 言語 | C (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 72 ms / 2,000 ms |
| コード長 | 2,618 bytes |
| コンパイル時間 | 437 ms |
| コンパイル使用メモリ | 31,872 KB |
| 実行使用メモリ | 13,568 KB |
| 最終ジャッジ日時 | 2024-10-06 11:49:36 |
| 合計ジャッジ時間 | 4,248 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 40 |
ソースコード
#include <stdio.h>
#include <stdlib.h>
#define N_MAX 100000
#define M_MAX 200000
typedef struct Edge {
struct Edge *next;
int v;
} edge;
void chmin(int* a, int b)
{
if (*a > b) *a = b;
}
int DFS_SCC(edge* adj[], int label[], int ord[], int low[], int s[], int* head, int u)
{
s[(*head)++] = u; // Add u to the stack (which maintains the vertices already found but not determined)
ord[u] = ord[0]++;
low[u] = ord[u];
int w;
edge *p;
for (p = adj[u]; p != NULL; p = p->next) {
w = p->v;
if (ord[w] == 0) chmin(&(low[u]), DFS_SCC(adj, label, ord, low, s, head, w)); // w has been found
else if (ord[w] <= N_MAX) chmin(&(low[u]), ord[w]); // w is already found but not determined
}
if (low[u] == ord[u]) { // A new SCC containing u has been determined
while (s[--(*head)] != u) {
label[s[*head]] = label[0];
ord[s[*head]] = N_MAX + 1;
}
label[u] = label[0]++;
ord[u] = N_MAX + 1;
}
return low[u];
}
int SCC(int N, edge* adj[], int label[], edge*** scc_adj, edge** scc_e)
{
int u, w, head;
static int ord[N_MAX + 1], low[N_MAX + 1], s[N_MAX + 1];
for (u = 1; u <= N; u++) {
label[u] = 0;
ord[u] = 0;
}
for (u = 1, label[0] = 1, ord[0] = 1; u <= N; u++) {
if (ord[u] != 0) continue;
head = 0;
DFS_SCC(adj, label, ord, low, s, &head, u);
}
int m = 0, n = label[0] - 1;
edge *p;
*scc_e = (edge*)malloc(sizeof(edge) * M_MAX);
*scc_adj = (edge**)malloc(sizeof(edge*) * (n + 1));
for (u = 1; u <= n; u++) (*scc_adj)[u] = NULL;
for (u = 1; u <= N; u++) {
for (p = adj[u]; p != NULL; p = p->next) {
w = p->v;
if (label[w] == label[u]) continue;
(*scc_e)[m].v = label[w];
(*scc_e)[m].next = (*scc_adj)[label[u]];
(*scc_adj)[label[u]] = &((*scc_e)[m++]);
}
}
*scc_e = (edge*)realloc(*scc_e, sizeof(edge) * m);
return n;
}
int main()
{
int i, N, M, u, w;
edge *adj[N_MAX + 1] = {}, e[M_MAX], *p;
scanf("%d %d", &N, &M);
for (i = 0; i < M; i++) {
scanf("%d %d", &u, &w);
e[i].v = w;
e[i].next = adj[u];
adj[u] = &(e[i]);
}
edge **scc_adj, *scc_e;
int label[N_MAX + 1], n = SCC(N, adj, label, &scc_adj, &scc_e), ns, nt, deg[N_MAX + 1][2], flag[N_MAX + 1];
if (n == 1) {
printf("0\n");
fflush(stdout);
return 0;
}
for (u = 1; u <= n; u++) {
deg[u][0] = 0; // Out-degree
deg[u][1] = 0; // In-degree
}
for (u = 1; u <= n; u++) {
for (p = scc_adj[u]; p != NULL; p = p->next) {
w = p->v;
deg[u][0]++;
deg[w][1]++;
}
}
for (u = 1, ns = 0, nt = 0; u <= n; u++) {
if (deg[u][0] == 0) nt++; // Sink
if (deg[u][1] == 0) ns++; // Source
}
printf("%d\n", (ns > nt)? ns: nt);
fflush(stdout);
return 0;
}