zoukankan      html  css  js  c++  java
  • 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; }
  • 相关阅读:
    【POJ 1958】 Strange Towers of Hanoi
    【HNOI 2003】 激光炸弹
    【POJ 3263】 Tallest Cow
    【POJ 2689】 Prime Distance
    【POJ 2777】 Count Color
    【POJ 1995】 Raising Modulo Numbers
    【POJ 1845】 Sumdiv
    6月16日省中集训题解
    【TJOI 2018】数学计算
    【POJ 1275】 Cashier Employment
  • 原文地址:https://www.cnblogs.com/372465774y/p/3206427.html
Copyright © 2011-2022 走看看