poj 3160 Father Christmas flymouse
2012-03-23 18:49
288 查看
类型:有向图连通性 + spfa求最长路
题目:http://poj.org/problem?id=3160
来源:POJ Monthly--2006.12.31,
Sempr
思路:强连通分量中的点可以相互到达,可以将其缩点,构造新有向无环图。如果要使结果最大,容易知道圣诞老人的起点是新图中节点入度为0的点。将新点的权赋值到对应的边上,则问题即是求从起点开始的最长路
!!!点权有负值
题目:http://poj.org/problem?id=3160
来源:POJ Monthly--2006.12.31,
Sempr
思路:强连通分量中的点可以相互到达,可以将其缩点,构造新有向无环图。如果要使结果最大,容易知道圣诞老人的起点是新图中节点入度为0的点。将新点的权赋值到对应的边上,则问题即是求从起点开始的最长路
!!!点权有负值
// poj 3160 Father Christmas flymouse // wa wa wa ac 1364K 125MS #include <iostream> #include <fstream> #include <algorithm> #include <queue> #include <stack> #include <string> #include <cmath> #include <cstring> using namespace std; #define MIN(a,b) (a < b ? a : b) #define clr(a,b) memset(a,b,sizeof(a)) #define FOR(i,a,b) for((i) = (a); (i) < (b); ++i) #define FORE(i,a,b) for((i) = (a); (i) <= (b); ++i) #define MAXN 30010 #define MAXM 300010 const int INF = 0x7f7f7f7f; bool in_stack[MAXN]; bool vis[MAXN]; int num, cnt, scnt, end_sum, m, n, cnt_num; int in[MAXN]; int cnt0[MAXN]; int dist[MAXN]; int endd[MAXN], val[MAXN]; int low[MAXN], step[MAXN]; int head[MAXN], shead[MAXN]; int belong[MAXN]; stack<int> st; struct edge { int v, nxt; }e[MAXM]; struct sedge { int v, nxt, w; }p[MAXM]; void addedge(int u, int v) { e[cnt].v = v; e[cnt].nxt = head[u]; head[u] = cnt++; } void addsedge(int u, int v) { p[scnt].v = v; p[scnt].w = endd[v]; p[scnt].nxt = shead[u]; shead[u] = scnt++; } void Tarjan(int u) { int v; int i,j; step[u] = low[u] = ++num; st.push(u); in_stack[u] = true; for(i = head[u]; i != -1; i = e[i].nxt) { v = e[i].v; if(!step[v]) { Tarjan(v); low[u] = MIN(low[u],low[v]); } else if(in_stack[v]) low[u] = MIN(low[u],step[v]); } if(step[u] == low[u]) { cnt_num++; int tmp_sum = 0; do{ j = st.top(); st.pop(); in_stack[j] = false; if(val[j] > 0) endd[cnt_num] += val[j]; belong[j] = cnt_num; }while(j != u); } } int spfa(int x) { int i; clr(dist, 0); clr(cnt0, 0); clr(vis, false); dist[x] = endd[x]; queue<int> q; q.push(x); vis[x] = true; ++cnt0[x]; while(!q.empty()){ int u = q.front(); q.pop(); vis[u] = false; for(i = shead[u]; i != -1; i = p[i].nxt){ int v = p[i].v; if(p[i].w + dist[u] > dist[v]){ dist[v] = p[i].w + dist[u]; if(!vis[v]){ q.push(v); vis[v] = true; if((++cnt0[v]) >= cnt_num) return -1; } } } } return 1; } void solve() { int i, j; FOR(i, 0, n) if(step[i] == 0) Tarjan(i); FOR(i, 0, n) for(j = head[i]; j != -1; j = e[j].nxt) if(belong[i] != belong[e[j].v]) { addsedge(belong[i], belong[e[j].v]); ++in[belong[e[j].v]]; } FORE(i, 1, cnt_num) if(in[i] == 0) { spfa(i); int tmp_sum = -INF; FORE(j, 1, cnt_num) tmp_sum = max(tmp_sum, dist[j]); end_sum = max(end_sum, tmp_sum); } printf("%d\n", end_sum); } void init() { int i, u, v; clr(head, -1); clr(shead, -1); clr(step, 0); clr(in, 0); clr(belong, 0); clr(endd, 0); clr(in_stack, false); num = cnt = scnt = end_sum = cnt_num = 0; FOR(i, 0, n) scanf("%d", &val[i]); FOR(i, 0, m) { scanf("%d %d", &u, &v); addedge(u, v); } } int main() { while(scanf("%d %d", &n, &m) != EOF) { init(); solve(); } return 0; }
相关文章推荐
- poj 3160 Father Christmas flymouse (SCC缩点+SPFA求最长路)
- POJ 3160 Father Christmas flymouse
- poj 3160 Father Christmas flymouse 强连通缩点+bfs
- POJ 3160 Father Christmas flymouse(强连通+DP)
- POJ 3160 Father Christmas flymouse 强连通分量+缩点+DP
- POJ 3160 Father Christmas flymouse 强连通+最长路
- POJ3160 Father Christmas flymouse[强连通分量 缩点 DP]
- POJ 3160 Father Christmas flymouse tarjan缩点+spfa求最长路
- poj 3160 Father Christmas flymouse
- POJ 3160 Father Christmas flymouse 强连通+Spfa
- POJ 3160 Father Christmas flymouse
- POJ 3160 Father Christmas flymouse 强连通缩点+spfa最长路
- POJ 3160 Father Christmas flymouse
- poj 3160 Father Christmas flymouse【强连通 DAG spfa 】
- POJ:3160-Father Christmas flymouse
- poj 3160 Father Christmas flymouse (强连通分量+记忆化搜素)
- poj 3160 Father Christmas flymouse(Tarjan+SPFA)
- Poj 3160 Father Christmas flymouse【强连通Tarjan+SPFA+超级源点】
- POJ-3160-Father Christmas flymouse 解题报告
- POJ - 3160 Father Christmas flymouse(最长路+强连通分量)