• poj 3160 Father Christmas flymouse


    // 题目描述:
    从武汉大学ACM集训队退役后,flymouse 做起了志愿者,帮助集训队做一些琐碎的事情,
    比如打扫集训用的机房等等。当圣诞节来临时,flymouse打扮成圣诞老人给集训队员发放礼物。
    集训队员住在校园通过宿舍的不同寝室里。为了节省体力,flymouse决定从某个寝室出发,沿着
    一些有向路一个接一个地访问寝室并顺便发放礼物,直到所有集训队员的起始走遍为止。
    以前flymouse在集训队的日子里,他给其他队员留下了不同的印象。他们中的一些人,比如
    LiZhiXu,对flymouse的印象特别好,将会为他的好心唱赞歌;而其他一些人,比如snoopy,将
    不会宽恕flymouse 的懒惰。flymouse 可以用一种安慰指数来量化他听了这些队员的话语后心情
    是好还是坏(正数表示是心情好,负数表示心情坏)。当到达一个寝室时,他可以选择进入寝室、
    发放礼物、倾听接收礼物的队员的话语,或者默默地绕开这个寝室。他可能会多次经过一个寝室,
    但决不会第二次进入该寝室。他想知道在他发放礼物的整个旅程,他收获安慰指数的最大数量。


    // 缩点 把强连通分量内的值加起来(负数就不加了吧 开始我没想到有负数 WA了)
    // 然后就是 DAG(无回路有向图)的单源最长路径 这个简单dp了
    // 先拓扑排序 根据拓扑排序进行dp 然后就OK了

    #include <iostream> #include <algorithm> #include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <string.h> using namespace std; #define MOD 1000000007 #define maxn 300100 #define maxm 30010 struct Edge{ int to; int next; Edge(){}; Edge(int u,int v){to=u;next=v;} }E[maxn]; stack<int> S; int V[maxm],num,sccV[maxm]; int belong[maxm]; int pre[maxm]; int dfst,scc; bool tag[maxm]; int in[maxm];//,out[maxm]; int val[maxm],sccval[maxm]; void init(int n){ dfst=scc=0; num=0; while(!S.empty()) S.pop(); for(int i=1;i<=n;i++){ V[i]=-1; pre[i]=0; belong[i]=0; } } void add(int u,int v){ E[num].to=v; E[num].next=V[u]; V[u]=num++; } void sccadd(int u,int v){ E[num].to=v; E[num].next=sccV[u]; sccV[u]=num++; } int tarjan(int u){ int lowu=pre[u]=++dfst; int v,e; S.push(u); for(e=V[u];e!=-1;e=E[e].next){ v=E[e].to; if(!pre[v]){ int lowv=tarjan(v); lowu=min(lowu,lowv); } else if(!belong[v]) lowu=min(lowu,pre[v]); } if(lowu==pre[u]){ scc++; sccval[scc]=0; for(;;){ int x=S.top();S.pop(); if(val[x]>0)// 记得把负数舍掉、居然还搞负数 害我wa了、去看了下讨论板才知道的、、
    sccval[scc]
    +=val[x];// scc 的val belong[x]=scc; if(x==u) break; } } return lowu; } int top[maxm],tn; void topsort(){ int i,e; tn=0; for(i=1;i<=scc;i++)tag[i]=0; while(1){ for(i=1;i<=scc;i++) if(!tag[i]&&!in[i]) break; if(i>scc) break; tag[i]=true; top[tn++]=i; for(e=sccV[i];e!=-1;e=E[e].next){ in[E[e].to]--; } } } int dis[maxm]; int main() { int n,m,T; int u,v; int i,j; //scanf("%d",&T); while(scanf("%d %d",&n,&m)!=EOF){ init(n); for(i=1;i<=n;i++){ scanf("%d",&val[i]); } for(i=1;i<=m;i++) { scanf("%d %d",&u,&v); add(u+1,v+1); } for(i=1;i<=n;i++) if(!pre[i]) tarjan(i); // for(i=1;i<=n;i++) printf("%d ",belong[i]); int ans=-MOD; for(i=1;i<=scc;i++) { in[i]=0; sccV[i]=-1; dis[i]=sccval[i]; ans=max(ans,dis[i]); } int e,u,v; for(i=1;i<=n;i++) { for(e=V[i];e!=-1;e=E[e].next){ u=belong[i]; v=belong[E[e].to]; if(u!=v){ in[v]++; // out[u]++;//,printf("v=%d ",v); sccadd(u,v); } } } topsort(); for(i=0;i<tn;i++){ u=top[i]; for(e=sccV[u];e!=-1;e=E[e].next){ v=E[e].to; if(dis[v]<dis[u]+sccval[v]){ dis[v]=dis[u]+sccval[v]; ans=max(dis[v],ans); } } } printf("%d ",ans); } return 0; }
  • 相关阅读:
    适用于Bash编程初学者小例子
    Linux下的压缩与解压命令速查
    Linux下拷贝一个带有soft link的dir,会把被link的内容也拷贝过来吗?
    适用于Bash编程初学者小例子
    从一个git仓库迁移代码到另一个git仓库(亲测有效版)(转)
    海量数据面试题(附题解+方法总结)(转)
    leetcode刷题(六)路径总和I、II、III(转)
    浅谈AVL树,红黑树,B树,B+树原理及应用(转)
    [LeetCode] 860. Lemonade Change 买柠檬找零(转)
    [leetcode] 134. Gas Station 解题报告(转)
  • 原文地址:https://www.cnblogs.com/372465774y/p/3206427.html
Copyright © 2020-2023  润新知