題意:
給乙個有向圖,邊有權值。
問最小的傳遞資訊代價,代價是邊的權值。
乙個相互可達的頂點之間交換資訊是不需要代價的,肯定存在乙個點能把資訊傳遞到其餘所有點。
思路:
強連通分量+topo排序,強連通縮點以後找到入度為0的點進行topo,儲存資訊傳遞到每個新點用的最小代價即可。
主要是題目描述太醜難以理解。
原始碼:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
#define ll long long
#define inf (1000000000)
const
int maxn = 50000;
int head1[maxn], cnt1;
int head2[maxn], cnt2;
struct edge
edge(int _u, int _v, int _val)
}edge1[100000 * 2 + 5], edge2[100000 * 2 + 5];
void add_edge1(int u, int v, int val)
void add_edge2(int u, int v, int val)
int low[maxn], pre[maxn], dfs_clock;
int vis[maxn];
int scc_cnt, sccno[maxn];
stack
sta;
void tarjan_scc(int u, int p)
else
if(!sccno[v])
}if(low[u] == pre[u])
}}bool cmp2(edge a, edge b)
int in[maxn];
int cost[maxn];
queue
que;
int main()
memset(pre, 0, sizeof(pre));
memset(low, 0, sizeof(low));
dfs_clock = 0;
memset(sccno, 0, sizeof(sccno));
scc_cnt = 0;
while(!sta.empty()) sta.pop();
for(int i = 0 ; i < n ; i++)
}memset(head2, -1, sizeof(head2));
cnt2 = 0;
memset(in, 0, sizeof(in));
for(int i = 0 ; i < cnt1 ; i++)
}memset(vis, 0, sizeof(vis));
ll ans = 0;
for(int i = 1 ; i <= scc_cnt ; i++)
cost[i] = inf;
for(int i = 1 ; i <= scc_cnt ; i++)
}while(!que.empty()) que.pop();
que.push(u);
cost[u] = 0;
while(!que.empty())
}for(int i = 1 ; i <= scc_cnt ; i++)
ans += cost[i];
// sort(edge2, edge2 + cnt2, cmp2);
// for(int i = 0 ; i < cnt2 ; i++)
// if(cnt == scc_cnt)
// break;
// }
printf("%i64d\n", ans);
}return
0;}
HDU 3072 強連通分量
題目鏈結 題目大意 為乙個有向連通圖加邊。使得整個圖全連通,有重邊出現。解題思路 先用tarjan把強連通分量縮點。由於整個圖肯定是連通的,所以列舉每一條邊,記錄到非0這個點所在連通分量的最小cost。一共需要累加cnt 1個連通分量的cost。在tarjan過程中的重邊,可以用鏈式前向星結構解決。...
HDU 3072 強連通分量
題目鏈結 題目大意 為乙個有向連通圖加邊。使得整個圖全連通,有重邊出現。解題思路 先用tarjan把強連通分量縮點。由於整個圖肯定是連通的,所以列舉每一條邊,記錄到非0這個點所在連通分量的最小cost。一共需要累加cnt 1個連通分量的cost。在tarjan過程中的重邊,可以用鏈式前向星結構解決。...
強連通縮點 hdu3072
題意 實現某確定一點向其他所有的點直接或者間接地傳遞訊息。如果某幾個點之間訊息可以互達,則不收取費用,求所有點接受到訊息所花費的最小值。連通分量內不收取費用,所以列舉找到聯通分量之間最小值。include include include includeusing namespace std defi...