程序博客网 > 北语网络教学平台
来源:互联网 发布:北语网络教学平台 编辑:程序博客网 时间:2024/06/08 03:04
http://poj.org/problem?id=3160
/*题意:一个老师要给学生送礼物,每个学生不在同一宿舍,现在题目一个n个学生,m个边,每个学生有一个值,要你求这个老师能得到的最大值scc+dpdp[i]表示走到节点i能取到的最大值*/#include<iostream>using namespace std;#define MAXN 30005#define MAXM 150005struct Node{int to;int next;}graph[MAXM], newgraph[MAXM];//原图,新图int head1[MAXN], head2[MAXN], cnt1, cnt2, pt;//建图用的两个数组int n, m;//顶点数,边数int low[MAXN], dfn[MAXN], stack[MAXN], belong[MAXN];//tarjan算法用的常用数组int index, num, top;bool instack[MAXN], visit[MAXN];int val[MAXN], newval[MAXN];int dp[MAXN];int tms[MAXN];//用来储存拓扑排序的顺序void init()//初始化{index = num = top = 0;cnt1 = 0;cnt2 = 0;pt = 0;for(int i=0; i<=n; i++){head1[i] = head2[i] = -1;low[i] = 0;dfn[i] = 0;instack[i] = false;visit[i] = false;val[i] = 0;newval[i] = 0;dp[i] = 0;}}inline int min(int a, int b){if(a < b)return a;elsereturn b;}inline int max(int a, int b){if(a>b)return a;elsereturn b;}//建立原图void addedge(int u, int v){graph[cnt1].to = v;graph[cnt1].next = head1[u];head1[u] = cnt1++;}//建立新图void newaddedge(int u, int v){newgraph[cnt2].to = v;newgraph[cnt2].next = head2[u];head2[u] = cnt2++;}//强连通分支算法模板void tarjan(int i){int j, e;dfn[i] = low[i] = index++;instack[i] = true;stack[top++] = i;for(e = head1[i]; e!=-1; e=graph[e].next){j = graph[e].to;if(!dfn[j]){tarjan(j);low[i] = min(low[i], low[j]);}else if(instack[j])low[i] = min(low[i], dfn[j]);}if(dfn[i] == low[i]){num++;do{j = stack[--top];instack[j] = false;belong[j] = num;}while(i!=j);}}//拓扑排序void topsort(int x){int i;visit[x] = true;for(i=head2[x]; i!=-1; i=newgraph[i].next){int e = newgraph[i].to;if(!visit[e])topsort(e);}tms[pt++] = x;}//建立新图的主程序void buildgraph(){int i, j;for(i=0; i<n; i++)if(val[i]>0)newval[belong[i]] += val[i];for(i=0; i<n; i++)for(j=head1[i]; j!=-1; j=graph[j].next)if(belong[i] != belong[graph[j].to]){newaddedge(belong[i], belong[graph[j].to]);//printf("%d %d/n", belong[i], belong[graph[j].to]);}}void solve(){int i, j;for(i=0; i<n; i++)if(!dfn[i])tarjan(i);buildgraph();memset(visit, 0, sizeof(visit));for(i=1; i<=num; i++)if(!visit[i])topsort(i);for(i=0; i<pt; i++){int w = tms[i], tmp = 0;dp[w] = newval[w];for(j=head2[w]; j!=-1; j=newgraph[j].next){tmp = max(tmp, dp[newgraph[j].to]);}dp[w] += tmp;}int ans = dp[1];for(i=2; i<=num; i++)ans = max(ans, dp[i]);printf("%d/n", ans);}int main(){//freopen("in.txt", "r", stdin);int i;while(scanf("%d %d", &n, &m) != EOF){init();for(i=0; i<n; i++)scanf("%d", &val[i]);int u, v;for(i=0; i<m; i++){scanf("%d %d", &u, &v);addedge(u, v);}solve();}return 0;}