【连通性,度数,拓扑 】【有向无环图的拓扑序】POJ 3249 Test for Job

【题目】http://poj.org/problem?id=3249

【大意】给定一些点,点上有权值,点之间有一些有向边,求从0入读点到0出度点距离的最大值。

【思路】拓扑序之后,按照拓扑序来松弛dis。

【参考】https://blog.csdn.net/LuRiCheng/article/details/53149412

【重点】拓扑排序

【代码】

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;

const int M=500005;
const int INF=2000000000;
class node
{
public:
    int v,next;
} edge[M*10];
int ei;
int head[M];
int n;
int dis[M];

int w[M];
bool books[M]= {0};
bool bookt[M]= {0};
bool used[M]= {0};
int TPO[M],ti;
void addedge(int u,int v)
{
    edge[++ei].v=v;
    edge[ei].next=head[u];
    head[u]=ei;
}

void topsort(int x)
{
    used[x]=1;
    for(int i=head[x]; i!=-1; i=edge[i].next)
    {
        int v=edge[i].v;
        if(used[v]==0)
            topsort(v);
    }
    TPO[ti++]=x;
    return;
}

int main()
{
    while(~scanf("%d",&n))
    {
        ti=0;
        memset(head,-1,sizeof(head));
        memset(books,0,sizeof(books));
        memset(bookt,0,sizeof(bookt));
        memset(used,0,sizeof(used));
        int m;
        scanf("%d",&m);
        for(int i=1; i<=n; i++)
            scanf("%d",&w[i]);
        for(int i=0; i<m; i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            addedge(u,v);
            books[u]=1;
            bookt[v]=1;
        }

        for(int i=1; i<=n; i++)
        {
            if(bookt[i]==0)
                dis[i]=w[i];
            else
                dis[i]=-INF;
            if(used[i]==0)
                topsort(i);
        }
        for(int i=n-1; i>=0; i--)
        {
            int t=TPO[i];
            for(int j=head[t]; j!=-1; j=edge[j].next)
            {
                int v=edge[j].v;
                dis[v]=max(dis[v],dis[t]+w[v]);
            }
        }

        int ans=-INF;
        for(int i=1; i<=n; i++)
        {
            if(books[i]==0)
                ans=max(ans,dis[i]);
        }
        printf("%d\n",ans);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_32259423/article/details/81392921