• 静态链表+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);
    }
    }



  • 相关阅读:
    第八周学习进度总结
    全国(球)疫情信息可视化
    第六周学习进度总结
    手把手教你爬取B站弹幕!
    Xpath基础学习
    团队成员及选题介绍
    第五周学习进度
    课堂练习之疫情APP
    SpringMVC02
    06 | 链表(上):如何实现LRU缓存淘汰算法?
  • 原文地址:https://www.cnblogs.com/huhuuu/p/2271223.html
Copyright © 2020-2023  润新知