POJ 3160 强联通缩点+最短路
| Time Limit: 1000MS | Memory Limit: 131072K | |
| Total Submissions: 2236 | Accepted: 754 |
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 N
distinct 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
题意:圣诞节,flymouse要给学生送礼,每个学生都有一个印象分值,他从某个房间出发,对于每个学生的房间他可以选择多次路过,但是只要进去,只能进一次,求走到头时的最大分值。
解题思路:由于图中可能存在环,所以先需要缩点,重新建图,把同一个连通分量中权值大于0的累加起来,他从入度为0的连通分量走到出度为0的连通分量所经过的最大权值为 答案,由于可能有多个
入度为,所以建立一个超级源点,把所有入度为0的连起来,然后跑一次spfa,取最大值即可。
代码:
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<set>
#include<list>
#include<vector>
#include<queue>
#include<stack>
#include<iterator>
#include<string>
#include<string.h>
#include<math.h>
#include<iomanip>
#include<stdlib.h>
#include<ctype.h>
#include<limits.h>
using namespace std;
typedef long long ll;
const ll maxn=50100;
ll head[maxn],tol,low[maxn],dfn[maxn],Stack[maxn],instack[maxn],belong[maxn],out[maxn],indexx,scc,top,in[maxn];
ll head1[maxn],tot,dist[maxn],weight[maxn],weight1[maxn],que[30*maxn],vis[maxn];
struct node
{
ll to,next,val;
}edge[30*maxn],edge1[maxn];
void add(ll u,ll v)
{
edge[tol].to=v;
edge[tol].next=head[u];
head[u]=tol++;
}
void add1(ll u,ll v,ll w)
{
edge1[tot].to=v;
edge1[tot].next=head1[u];
edge1[tot].val=w;
head1[u]=tot++;
}
void tarjin(ll u)
{
low[u]=dfn[u]=++indexx;
Stack[top++]=u;instack[u]=1;
ll i,v;
for(i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].to;
if(!dfn[v])
{
tarjin(v);
if(low[u]>low[v])low[u]=low[v];
}
else if(instack[v]&&low[u]>dfn[v])low[u]=dfn[v];
}
if(low[u]==dfn[u])
{
scc++;
do
{
v=Stack[--top];
instack[v]=0;
belong[v]=scc;
}while(u!=v);
}
}
void solve(ll n)
{
memset(belong,0,sizeof(belong));
memset(dfn,0,sizeof(dfn));
memset(instack,0,sizeof(instack));
indexx=top=scc=0;
for(ll i=1;i<=n;i++)
if(!dfn[i])tarjin(i);
//cout<<scc<<endl;
}
void rebuild(int n)
{
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(head1,-1,sizeof(head1));tot=0;
memset(weight1,0,sizeof(weight1));
int i,u,v,j;
for(i=1;i<=n;i++)if(weight[i]>0)weight1[belong[i]]+=weight[i];
for(u=1;u<=n;u++)
{
for(i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].to;
if(belong[u]!=belong[v])
{
add1(belong[u],belong[v],weight1[belong[v]]);
in[belong[v]]++;
out[belong[u]]++;
}
}
}
for(i=1;i<=scc;i++)
if(in[i]==0)add1(0,i,weight1[i]);
}
void spfa(ll st)
{
memset(dist,0,sizeof(dist));
memset(vis,0,sizeof(vis));vis[st]=1;
ll front=0,rear=0;
que[rear++]=st;
while(front!=rear)
{
ll u=que[front++];
vis[u]=0;
for(ll i=head1[u];i!=-1;i=edge1[i].next)
{
ll v=edge1[i].to;
if(dist[v]<dist[u]+edge1[i].val)
{
dist[v]=dist[u]+edge1[i].val;
if(vis[v]==0)
{
vis[v]=1;
que[rear++]=v;
}
}
}
}
}
int main()
{
ll i,j,k,m,n;
while(~scanf("%lld%lld",&n,&m))
{
memset(head,-1,sizeof(head));tol=0;
for(i=1;i<=n;i++)scanf("%lld",&weight[i]);
while(m--)
{
scanf("%lld%lld",&i,&j);
add(i+1,j+1);
}
solve(n);
rebuild(n);
spfa(0);
ll ans=0;
for(i=1;i<=scc;i++)
if(out[i]==0)
{
if(ans<dist[i])ans=dist[i];
}
printf("%d\n",ans);
}
return 0;
}

浙公网安备 33010602011771号