【强连通分量+缩点】 HDOJ 1827 Summer Holiday

来源:互联网 发布:mac nestopia金手指 编辑:程序博客网 时间:2024/05/19 05:40

先求出强连通分量,每个强连通分量都可以看成一个点,这个点的权值是这个连通分量重权值最小的,然后计算一下所有点的入度,入度为0的点的个数和权值和就是答案了。。

#include <iostream>  #include <queue>  #include <stack>  #include <map>  #include <set>  #include <bitset>  #include <cstdio>  #include <algorithm>  #include <cstring>  #include <climits>  #include <cstdlib>#include <cmath>#include <time.h>#define maxn 1005#define maxm 4005#define eps 1e-10#define mod 1000000009#define INF 99999999  #define lowbit(x) (x&(-x))  //#define lson o<<1, L, mid  //#define rson o<<1 | 1, mid+1, R  typedef long long LL;//typedef int LL;using namespace std;int H[maxn], v[maxm], next[maxm];int h[maxn], vv[maxm], nn[maxm];int dfn[maxn], low[maxn];int id[maxn], in[maxn], du[maxn];int vis[maxn], n, m, top;int w[maxn];stack<int> s;void read(void){int a, b, i, cnt = 0;for(i = 1; i <= n; i++) scanf("%d", &w[i]);while(m--) {scanf("%d%d", &a, &b);next[cnt] = H[a], v[cnt] = b, H[a] = cnt, cnt++;}}void init(void){top = 0;memset(H, -1, sizeof H);memset(h, -1, sizeof h);memset(du, 0, sizeof du);memset(in, 0 ,sizeof in);memset(vis, 0, sizeof vis);memset(dfn, 0, sizeof dfn);}void build(void){int i, cnt = 0;for(i = 1; i <= n; i++)for(int e = H[i]; ~e; e = next[e])nn[cnt] = h[id[i]], h[id[i]] = cnt, vv[cnt] = id[v[e]], cnt++;}void tarjan(int u){dfn[u] = low[u] = ++top;s.push(u), in[u] = 1;for(int e = H[u]; ~e; e = next[e]) {if(!dfn[v[e]]) {tarjan(v[e]);low[u] = min(low[u], low[v[e]]);}else if(in[v[e]]) low[u] = min(low[u], dfn[v[e]]);}if(dfn[u] == low[u]) {int tmp = s.top(); s.pop(), in[tmp] = 0;while(tmp != u) {id[tmp] = u;w[u] = min(w[u], w[tmp]);tmp = s.top();s.pop();in[tmp] = 0;}id[tmp] = u;}}void work(void){int ans = 0, cost = 0;for(int i = 1; i <= n; i++)if(!dfn[i]) tarjan(i);build();for(int i = 1; i <= n; i++)for(int e = h[i]; ~e; e = nn[e])if(vv[e] != i)du[vv[e]]++;for(int i = 1; i <= n; i++)if(!vis[id[i]] && !du[id[i]])vis[id[i]] = 1, ans++, cost += w[id[i]];printf("%d %d\n", ans, cost);}int main(void){while(scanf("%d%d", &n, &m)!=EOF) {init();read();work();}return 0;}


0 0
原创粉丝点击