现在的位置: 首页 > 综合 > 正文

poj 3160 Father Christmas flymou…

2018年03月17日 ⁄ 综合 ⁄ 共 1534字 ⁄ 字号 评论关闭
题意:圣诞节,flymouse 要给学生送礼物,他从任意一个房间出发,每打开门送出礼物后,每个学生有一个值(可正可负),
他可以多次路过不进,但进的话只能进一次。flymouse走到头,求他能得到的最大值

思路:因为有环,所以进行缩点 构建新图 但新的图可能有多个入度出度为0的点,如果用枚举的话 时间可能会超
可以建立一个超级源点,把所有入度为0的点连起来,然后求src到 出度为0的点中值最大的就OK

#include <stdio.h>
#include <string.h>
#define VM 30005
#define EM 150050

int
val[VM],newval[VM],head[VM],head1[VM],p,n;//val[]是原点的值,newval是缩点的点的值

int vis[VM],belong[VM],dfn[VM],low[VM],stack[VM]; 
//这是tarjan的常用数组变量
int indeg[VM],outdeg[VM];
int scc,top,cnt,src = 0;  //src 为超级源点
struct E
{
    int
to,next;
}edge[EM];  //旧图
struct E1
{
    int
to,next,cost;
}edge1[EM];//新图
void addedge (int cu,int cv)
{
    edge[p].to =
cv;
    edge[p].next
= head[cu];
    head[cu] = p
++;
}
void addedge1 (int cu,int cv,int cw)
{
    edge1[p].to
= cv;
   
edge1[p].cost = cw;
   
edge1[p].next = head1[cu];
    head1[cu] =
p ++;
}
void tarjan (int
u)           
//tarjan算法缩点
{
    int v;
    dfn[u] =
low[u] = ++cnt;
    stack[top++]
= u;
    vis[u] =
1;
    for (int i =
head[u];i != -1;i = edge[i].next)
    {
       
v = edge[i].to;
       
if (!dfn[v])
       
{
           
tarjan(v);
           
low[u] = low[u] < low[v]?low[u]:low[v];
       
}
       
else if (vis[v]&& low[u]
> dfn[v])
           
low[u] = dfn[v];
    }
    if (dfn[u]
== low[u])
    {
       
++scc;
       
do
       
{
           
v = stack[--top];
           
vis[v] = 0;
           
belong[v] = scc;
       
}while (u != v);
    }
}
void sovle ()
{
    scc = top =
cnt = 0;
    memset
(vis,0,sizeof(vis));
    memset
(dfn,0,sizeof(dfn));
    for (int u =
1;u <= n;u ++)
       
if (!dfn[u])
           
tarjan(u);
}
void new_graph()
{
    int
u,v,i;
    memset
(newval,0,sizeof(newval));
    memset
(indeg,0,sizeof(indeg));
    memset
(outdeg,0,sizeof(outdeg));
    for(u = 1;u
<= n;u ++)  //每个强连通中的正值加起是最大的
  

抱歉!评论已关闭.