静态链表+DFS——poj 3272

http://poj.org/problem?id=3272

由于数据顶点5000,边50000

所以用静态链表

出度为0有多个,入度为0的点有一个

用f[i]表示i到出度为0的点 的边 有几条

g[j]表示j到入度为0的点 的边 有几条

两次dfs

一条边的起点qi,终点end

结果Max=max(f[qi]*g[end])

 

注意点:重边有效

View Code
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
const int N=5009;

struct data
{
int x,y;
}s[N*10];

struct node
{
int to;
int next;
}e[N*10],fe[N*10];
int pre[N*10],fpre[N*10];

bool used[N];
int f[N],g[N];

void dfs(int qi)
{
used[qi]=1;
int ok=0;
for(int k=fpre[qi];k!=-1;k=fe[k].next)
{
int to=fe[k].to;
if(used[to]==0)dfs(to);
f[qi]+=f[to];

ok=1;
}
if(ok==0)
f[qi]=1;//起点为1
}

void dfs2(int qi)
{
used[qi]=1;
for(int k=pre[qi];k!=-1;k=e[k].next)
{
int to=e[k].to;
if(used[to]==0)dfs2(to);
g[qi]+=g[to];
}
}

int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
int i,x,y;
int index=1;
memset(fpre,-1,sizeof(fpre));//pre两个都要赋初值
memset(pre,-1,sizeof(pre));
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
s[i].x=x;s[i].y=y;
e[index].to=y;e[index].next=pre[x];pre[x]=index;
fe[index].to=x;fe[index].next=fpre[y];fpre[y]=index++;
}

memset(used,0,sizeof(used));
memset(f,0,sizeof(f));
memset(g,0,sizeof(g));

dfs(n);//终点n只有一个, 到 各个出度为0的点,所以dfs一次

memset(used,0,sizeof(used));
g[n]=1;//终点为1
for(i=1;i<=n;i++)//起点可能有多个,所以dfs多次
{
if(used[i]==0)
dfs2(i);
}

int Max=0;
for(i=1;i<=m;i++)
{
x=s[i].x;y=s[i].y;
Max=max(Max,f[x]*g[y]);
}
printf("%d\n",Max);
}
}



你可能感兴趣的:(poj)