Road Repairs(CF 240E)

來源:互聯網
上載者:User

題目連結:http://codeforces.com/problemset/problem/240/E

題意:一個五萬個點和五萬條邊的圖,每條邊的邊權為1或0,問以1為根的最小樹形圖,並輸出方案。

解法:傳統最小樹形圖的複雜度為VE,但此圖邊權比較特殊,最小樹形圖的定義為除根節點外每個點都有入邊,根節點有出邊,且無環。因此可以首先使用邊權為0的邊為每個點找一條入邊,對於仍然沒有入度的點再使用邊權為1的邊,但只要無法處理0邊形成的環,因此要首先對0邊的樹進行強連通縮點,對於縮點後的dag先用0邊為每個點找入邊,然後利用類似於prim的思想:將當前根節點能夠延伸到的點放到隊列中(開始時隊列中的點為根節點),對於取出每個點的鄰接邊,如果臨界點未被訪問則排入佇列,如果臨界點未被訪問且邊權為1則此邊是最終答案中的邊。

import java.io.File;import java.io.FileNotFoundException;import java.io.IOException;import java.io.PrintStream;import java.util.Arrays;import java.util.Scanner;public class e {int maxn = 100010;class node {int id, be, ne, val;node(int i, int b, int e, int v) {id = i;be = b;ne = e;val = v;}}class SCC {int E[] = new int[maxn], len;node buf[] = new node[maxn];int dfn[] = new int[maxn], low[] = new int[maxn], cnt;int stack[] = new int[maxn], top;boolean instack[] = new boolean[maxn];int id[] = new int[maxn], n, idx;void init(int n) {this.n = n;Arrays.fill(E, -1);len = 0;}void add(int i, int a, int b, int v) {buf[len] = new node(i, b, E[a], v);E[a] = len++;}void dfs(int a) {dfn[a] = low[a] = ++cnt;instack[a] = true;stack[top++] = a;int b = -1;for (int i = E[a]; i != -1; i = buf[i].ne) {b = buf[i].be;if (buf[i].val != 0)continue;if (dfn[b] == 0) {dfs(b);if (low[b] < low[a])low[a] = low[b];} else if (instack[b])low[a] = Math.min(low[a], dfn[b]);}if (low[a] == dfn[a]) {idx++;do {b = stack[--top];instack[b] = false;id[b] = idx;} while (b != a);}}void solve() {cnt = idx = top = 0;Arrays.fill(dfn, 0);Arrays.fill(low, 0);Arrays.fill(instack, false);for (int i = 1; i <= n; i++)if (dfn[i] == 0)dfs(i);}void shrink() {dp.init(idx);dp.rt = id[1];for (int a = 1; a <= n; a++)for (int i = E[a]; i != -1; i = buf[i].ne) {int b = buf[i].be;if (id[a] != id[b])dp.add(buf[i].id, id[a], id[b], buf[i].val);}}}class DP {int E[] = new int[maxn], len, n, rt;node buf[] = new node[maxn];void add(int i, int a, int b, int v) {buf[len] = new node(i, b, E[a], v);E[a] = len++;}void init(int n) {this.n = n;Arrays.fill(E, -1);len = 0;}boolean vis[] = new boolean[maxn];void dfs(int a) {if (vis[a])return;vis[a] = true;for (int i = E[a]; i != -1; i = buf[i].ne)dfs(buf[i].be);}void solve() {dfs(rt);for (int i = 1; i <= n; i++)if (!vis[i]) {ps.println(-1);return;}Arrays.fill(vis, false);for (int i = 0; i < len; i++)if (buf[i].val == 0)vis[buf[i].be] = true;int ans = 0;vis[rt] = true;for (int i = 1; i <= n; i++)if (!vis[i])ans++;ps.println(ans);if (ans == 0)return;int stack[] = new int[n + 10], top = 0;boolean instack[] = new boolean[n + 10];stack[++top] = rt;instack[rt] = true;while (top != 0) {int a = stack[top--];for (int i = E[a]; i != -1; i = buf[i].ne) {int b = buf[i].be;if (!vis[b]){vis[b] =instack[b]= true;stack[++top] = b;ps.print(buf[i].id+" ");}else if (!instack[b]&&buf[i].val==0) {stack[++top] = b;instack[b] = true;}}}ps.println();}}DP dp = new DP();SCC scc = new SCC();PrintStream ps;Scanner scan;int n, m;void run() throws FileNotFoundException {scan = new Scanner(new File("input.txt"));ps = new PrintStream(new File("output.txt"));n = scan.nextInt();m = scan.nextInt();scc.init(n);for (int i = 1; i <= m; i++)scc.add(i, scan.nextInt(), scan.nextInt(), scan.nextInt());scc.solve();scc.shrink();dp.solve();}public static void main(String[] args) throws IOException {new e().run();}}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.