ディレクトリ
@説明@
与えられた各側に有向グラフは一度尋ねません。
この裏返した後、強く原画像の影響の構成要素を接続?
点の数N≤1000の縁M≤200000の数。
@解決@
推測時間をあえて、5秒の時間を参照してください複雑さO(NM)。
エッジは、U-> V影響を逆転:
他の経路は、UからVに存在しない場合強連結成分(V Uへのパスの存在に相当)、このエッジは、強連結フリップ減少場合。
ない場合はuからvへの別のパスがある場合には、フリップは強く接続され上昇しました。
エッジU-> Vのためのものであることを、我々は2つのことを宣告する必要が:Uへ、Vからのパスがあるかどうか、uからvへの別の経路がある場合。
暴力的なO(NM)の前に行うことができ、また、強連結を記述する必要はありません。
後者については。私たちは別のパス手段考えるもの:開始点として、またUなしのuへの道、U-> Vパスよりも第1のエッジがあります。
この経路は、第一の側の各点xに対して決定された場合に、図は、完全な各点Uの検索は、唯一のものです。
これを2回(一つだけ、1個以下)に更新されますどれだけ、なぜなら各ポイントのステータスの見つけることができます。
@acceptedコード@
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int MAXN = 1000;
const int MAXM = 200000;
vector<int>G[MAXN + 5]; int to[MAXM + 5];
void addedge(int u, int i) {G[u].push_back(i);}
int tag[MAXN + 5], que[2*MAXN + 5];
bool ans1[MAXM + 5], ans2[MAXM + 5];
int n, m;
int main() {
scanf("%d%d", &n, &m);
for(int i=1;i<=m;i++) {
int a; scanf("%d%d", &a, &to[i]);
addedge(a, i);
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) tag[j] = 0;
int s = 1, t = 0;
for(int p=0;p<G[i].size();p++)
tag[que[++t] = to[G[i][p]]] = G[i][p];
while( s <= t ) {
int x = que[s++], y = tag[x];
for(int p=0;p<G[x].size();p++) {
int q = to[G[x][p]];
if( q != i ) {
if( tag[q] != -1 ) {
if( tag[q] == 0 )
tag[que[++t] = q] = y;
else if( tag[q] != y )
tag[que[++t] = q] = -1;
}
}
else ans1[G[x][p]] = 1;
}
}
for(int p=0;p<G[i].size();p++)
if( tag[to[G[i][p]]] == -1 ) ans2[G[i][p]] = 1;
}
for(int i=1;i<=m;i++)
puts(ans1[i] ^ ans2[i] ? "diff" : "same");
}
詳細@
前のチェーンに比べて、この密なグラフ、ベクトル記憶速いメモリ(と、より親しみやすいキャッシュ)との星のように。具体的には、大きな影響のこの定数問題。
キャッシュ用としてGeshaです。。。学んだ私のTHUWC2020エントリによると、おそらくメモリに加えて、CPUがそれはキャッシュと呼ばれる、より最近の一時的なスペースがあります。
あなたは同じ要素へのアクセス権を持っている場合は、キャッシュにそれは非常に友好的であるため、高速になります。