您的位置:首页 > 其它

poj 3160 Father Christmas flymouse(Tarjan+SPFA)

2015-04-03 16:39 477 查看
Language:
Default

Father Christmas flymouse

Time Limit: 1000MSMemory Limit: 131072K
Total Submissions: 2784Accepted: 929
Description

After retirement as contestant from WHU ACM Team, flymouse volunteered to do the odds and ends such as cleaning out the computer lab for training as extension of his contribution to the team. When Christmas came, flymouse played Father Christmas to give
gifts to the team members. The team members lived in distinct rooms in different buildings on the campus. To save vigor, flymouse decided to choose only one of those rooms as the place to start his journey and follow directed paths to visit one room after
another and give out gifts en passant until he could reach no more unvisited rooms.

During the days on the team, flymouse left different impressions on his teammates at the time. Some of them, like LiZhiXu, with whom flymouse shared a lot of candies, would surely sing flymouse’s deeds of generosity, while the others, like snoopy, would
never let flymouse off for his idleness. flymouse was able to use some kind of comfort index to quantitize whether better or worse he would feel after hearing the words from the gift recipients (positive for better and negative for worse). When arriving at
a room, he chould choose to enter and give out a gift and hear the words from the recipient, or bypass the room in silence. He could arrive at a room more than once but never enter it a second time. He wanted to maximize the the sum of comfort indices accumulated
along his journey.

Input

The input contains several test cases. Each test cases start with two integers N and M not exceeding 30 000 and 150 000 respectively on the first line, meaning that there were N team members living in Ndistinct rooms and M direct
paths. On the next N lines there are N integers, one on each line, the i-th of which gives the comfort index of the words of the team member in the i-th room. Then follow M lines, each containing two integers i and j indicating
a directed path from the i-th room to the j-th one. Process to end of file.

Output

For each test case, output one line with only the maximized sum of accumulated comfort indices.

Sample Input
2 2
14
21
0 1
1 0

Sample Output
35

Hint

32-bit signed integer type is capable of doing all arithmetic.

Source

POJ Monthly--2006.12.31, Sempr

一个人从某个寝室开始给大家送礼物 每个寝室里面 会有一个安慰指数 求出这个人走下来能获得最大指数值

线路中间可能有环 所以需要先缩点 缩点过程中保存每个连通分量中的安慰指数值 正的才加进去

各个连通分量之间添加边 权值为到达点的安慰值 然后添加一个源点s

入度为0的连通分量作为每条路的起点 s与这些点之间建边 权值为这些点的安慰值

跑SPFA求最大值!!!

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>

#define MEM(a,x) memset(a,x,sizeof a)
#define eps 1e-8
#define MOD 10009
#define INF 0x3f3f3f3f
#define ll __int64
#define bug cout<<"here"<<endl
#define fread freopen("ceshi.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)

using namespace std;

void read(int &x)
{
    char ch;
    x=0;
    while(ch=getchar(),ch!=' '&&ch!='\n')
    {
        x=x*10+ch-'0';
    }
}

const int MAXN=30010;
const int MAXM=150010;
struct Edge
{
    int to,next;
}edge[MAXM];
int head[MAXN],tot;
int low[MAXN],dfn[MAXN],sta[MAXN],belong[MAXN];
int Index,top;
int scc;
bool instack[MAXN];
int num[MAXN];
int n,m;
int a[MAXN];
int b[MAXN],c[MAXN];//用来存储点
int in[MAXN],out[MAXN];
vector<int> vec[MAXN];

void addedge(int u,int v)
{
    edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++;
}

void Tarjan(int u)
{
    int v;
    low[u]=dfn[u]=++Index;
    sta[top++]=u;
    instack[u]=1;
    for(int i=head[u];i!=-1;i=edge[i].next)
    {
        v=edge[i].to;
        if(!dfn[v])
        {
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instack[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(low[u]==dfn[u])
    {
        scc++;
        do{
            v=sta[--top];
            instack[v]=0;
            belong[v]=scc;
            if(a[v]>0)
                num[scc]+=a[v];
        }while(u!=v);
    }
}

void solve()
{
    for(int i=1;i<=n;i++)
        if(!dfn[i])
            Tarjan(i);
}//Tarjan 部分

void init()
{
    MEM(head,-1);
    tot=0;
    MEM(dfn,0);
    MEM(num,0);
    MEM(instack,0);
    Index=scc=top=0;
    MEM(out,0);
    MEM(in,0);
}

struct EDGE
{
    int v,cost;
    EDGE(int _v,int _cost):v(_v),cost(_cost){}
};
vector<EDGE> E[MAXN];
void addEDGE(int u,int v,int w)
{
    E[u].push_back(EDGE(v,w));
}

bool vis[MAXN];
int dis[MAXN];
int SPFA(int start,int N)
{
    MEM(vis,0);
    for(int i=1;i<=N;i++) dis[i]=0;
    vis[start]=1;
    dis[start]=0;
    queue<int> que;
    while(!que.empty())  que.pop();
    que.push(start);
    while(!que.empty())
    {
        int u=que.front(); que.pop();
        vis[u]=0;
        for(int i=0;i<E[u].size();i++)
        {
            int v=E[u][i].v;
            if(dis[v]<dis[u]+E[u][i].cost)
            {
                dis[v]=dis[u]+E[u][i].cost;
                if(!vis[v])
                {
                    vis[v]=1;
                    que.push(v);
                }
            }
        }
    }
    int ans=0;
    for(int i=1;i<=N;i++)
    {
        if(out[i]==0)
            ans=max(ans,dis[i]);
    }
    return ans;

}

int main()
{
//    fread;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        init();
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&b[i],&c[i]);
            b[i]++; c[i]++;
            addedge(b[i],c[i]);
        }
        solve();
        for(int i=0;i<MAXN;i++)  E[i].clear();
        for(int i=1;i<=m;i++)
        {
            int u=belong[b[i]];
            int v=belong[c[i]];
            if(u!=v)
            {
                in[v]++;
                out[u]++;
                addEDGE(u,v,num[v]);
            }
        }
        for(int i=1;i<=scc;i++)
        {
            if(in[i]==0)
                addEDGE(0,i,num[i]);
        }
        int ans=SPFA(0,scc);
        printf("%d\n",ans);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: