2019 ICPC Malaysia National G(拓扑排序)

2019 ICPC Malaysia National G

有点绕,两层拓扑排序。

有空再补详细。

甚至有点丑,因为绕,为了区分,当时变量名写得很长。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
#define debug printf("!")
using namespace std;
typedef __int64 ll;
const int mod=1e9+7;
const int maxn=2e4+5;
const int inf=0x3f3f3f3f;

int main()
{
    int m,n,u,v,i,j,k,l,y,r,e;
    int K[maxn];
    ll Q[maxn]={0};
    vector<int> pointtextdepend[maxn][110];
    vector<int> pointdepend[maxn];
    vector<int> pointtextque[maxn];
    vector<int> pointque;
    int In[maxn]={0};
    int textqua[maxn][110][2];
    scanf("%d%d",&n,&m);
    for(u=1;u<=n;u++)
    {
        int in[110]={0};
        scanf("%d",&k);K[u]=k;
        for(i=1;i<=k;i++)
        {
            scanf("%d",&l);
            for(j=1;j<=l;j++)
            {
                scanf("%d",&y);
                pointtextdepend[u][i].push_back(y);
                in[y]++;
            }
            scanf("%d%d",&textqua[u][i][0],&textqua[u][i][1]);
            if(textqua[u][i][0])
            {
                pointdepend[u].push_back(textqua[u][i][1]);
                In[textqua[u][i][1]]++;
            }
        }
        queue<int>q;
        for(i=1;i<=k;i++)
            if(in[i]==0)q.push(i);
        while(!q.empty())
        {
            int p=q.front(); q.pop();
            pointtextque[u].push_back(p);
            for(int i=0;i<pointtextdepend[u][p].size();i++)
            {
                y=pointtextdepend[u][p][i];
                in[y]--;
                if(in[y]==0)
                    q.push(y);
            }
        }
    }
    queue<int>q;
    for(i=1;i<=n;i++)
        if(In[i]==0) q.push(i);
    while(!q.empty())
    {
        int p=q.front(); q.pop();
        pointque.push_back(p);
        for(i=0;i<pointdepend[p].size();i++)
        {
            y=pointdepend[p][i];
            In[y]--;
            if(In[y]==0)
                q.push(y);
        }
    }
    for(v=n-1;v>=0;v--)
    {
        u=pointque[v];
        ll ans=0;
        ll textcaltime[110]={0};
        for(i=K[u]-1;i>=0;i--)
        {
            ll x,y=0;
            if(textqua[u][pointtextque[u][i]][0])x=(Q[textqua[u][pointtextque[u][i]][1]]+1)%mod;
            else x=textqua[u][pointtextque[u][i]][1];
            if(pointtextdepend[u][pointtextque[u][i]].size()==0)
            {
                textcaltime[pointtextque[u][i]]=x%mod;
                ans=max(ans,x)%mod;
                continue;
            }
            for(j=0;j<pointtextdepend[u][pointtextque[u][i]].size();j++)
            {
                y=max(y,(ll)textcaltime[pointtextdepend[u][pointtextque[u][i]][j]]);
            }
            textcaltime[pointtextque[u][i]]=(x+y)%mod;
            ans=max(ans,(x+y)%mod);
        }
        Q[u]=ans;
    }
    for(i=1;i<=m;i++)
    {
        scanf("%d",&v);
        printf("%I64d\n",Q[v]);
    }
}

2019-09-06

原文地址:https://www.cnblogs.com/kkkek/p/11470637.html

时间: 2024-10-12 15:31:14

2019 ICPC Malaysia National G(拓扑排序)的相关文章

2019 ICPC Malaysia National F(状态压缩)

2019 ICPC Malaysia National F 赛后补题.看了这个题解,说是状态压缩. 以第一行的士兵为主,第二行士兵为次,即,第二行被第一行士兵匹配,更新第一行士兵的状态. 用当前第i个士兵的状态更新第i+1个士兵的状态. f[i][j]:i为士兵的下标,j为第i个士兵的状态.(1<j<(1<<(e*2+1))). 比如e=3,二进制 j=1000011,表示第i个士兵之前包括第i个士兵,在[i-3,i+3]范围内,第二行的士兵已被匹配了下标为i-3,i+2,i+3的

2019 ICPC Malaysia National H题

题意:给定n个点,求出这些点构成的凸包,然后逆时针输出,另外还有q次询问,每次询问一个点是否在凸包里. 题解:二维凸包裸题,直接利用叉积判断点是否在凸包内即可,时间复杂度n2,不知为何这题给了15s,然后我代码只跑了15ms #include <bits/stdc++.h> using namespace std; double eps=1e-15; double pi=acos(-1); struct Point{ double x,y; Point(double x=0,double y=

拓扑排序判断有向图是否有回路

1 #include <iostream> 2 #include <queue> 3 #include <string> 4 using namespace std; 5 6 //表结点 7 typedef struct ArcNode{ 8 int adjvex;//该弧所指向的顶点的位置 9 ArcNode *nextarc; 10 }ArcNode; 11 12 //头结点 13 typedef struct VNode{ 14 string data;//顶点信

拓扑排序介绍

拓扑排序介绍 拓扑排序(Topological Order)是指,将一个有向无环图(Directed Acyclic Graph简称DAG)进行排序进而得到一个有序的线性序列. 这样说,可能理解起来比较抽象.下面通过简单的例子进行说明! 例如,一个项目包括A.B.C.D四个子部分来完成,并且A依赖于B和D,C依赖于D.现在要制定一个计划,写出A.B.C.D的执行顺序.这时,就可以利用到拓扑排序,它就是用来确定事物发生的顺序的. 在拓扑排序中,如果存在一条从顶点A到顶点B的路径,那么在排序结果中B

数据结构课设——有向图的深度、广度优先遍历及拓扑排序

任务:给定一个有向图,实现图的深度优先, 广度优先遍历算法,拓扑有序序列,并输出相关结果. 功能要求:输入图的基本信息,并建立图存储结构(有相应提示),输出遍历序列,然后进行拓扑排序,并测试该图是否为有向无环图,并输出拓扑序列. 按照惯例,先上代码,注释超详细: #include<stdio.h> #include<stdlib.h> #include<malloc.h> #pragma warning(disable:4996) #define Max 20//定义数

HDU 5438 Ponds (拓扑排序+DFS)2015 ACM/ICPC Asia Regional Changchun Online

[题目链接]:click here~~ [题目大意]: 题意:在一个无向图中有 p 个点, m 条边,每个点有一个值 vi .不断的删去度数小于2的点直到不能删为止.求新图中所有点个数为奇数的连通分量的点值的和. 1<p<10^4,1<m<10^5 [思路]删边考虑类似拓扑排序的写法,不过topsort是循环一遍1到n结点入度为0的结点,然后加入到队列中,这里只要改一下度数小于等于1,最后DFS 判断一下 挫挫的代码: /* * Problem: HDU No.5438 * Run

ACM/ICPC 之 数据结构-邻接表+DP+队列+拓扑排序(TshingHua OJ-旅行商TSP)

做这道题感觉异常激动,因为在下第一次接触拓扑排序啊= =,而且看了看解释,猛然发现此题可以用DP优化,然后一次A掉所有样例,整个人激动坏了,哇咔咔咔咔咔咔咔~ 咔咔~哎呀,笑岔了- -|| 旅行商(TSP) Description Shrek is a postman working in the mountain, whose routine work is sending mail to n villages. Unfortunately, road between villages is

ACM/ICPC 之 拓扑排序-反向(POJ3687)

难点依旧是题意....需要反向构图+去重+看题 POJ3687-Labeling Balls 题意:1-N编号的球,输出满足给定约束的按原编号排列的重量序列,如果有多组答案,则输出编号最小的Ball重量最轻,若依旧多组则输出编号次小的Ball重量最轻的方案. 题解:在看懂题意后,再开始做会省很多时间...曲解题意还真是人类的本能啊. 为了完成单向关系排序,需要用到拓扑排序: 为了符合编号最小的重量最轻...的题意,需要用到反向拓扑排序: 输入可能会有重复的关系,因此需要判重: 输出需要按原编号输

ACM/ICPC 之 拓扑排序+DFS(POJ1128(ZOJ1083))

经典的拓扑排序问题,难点在于字典序输出和建立拓扑图,另外理解题意是最难的难点,没有之一... POJ1128(ZOJ1083)-Frame Stacking 题意:每个图片由同一字母组成的边框表示,每个图片的字母都不同: 在一个最多30*30的区域放置这些图片,问底层向顶层叠加的图片次序,多选时按字典序输出 注:每个图片的四边都会有字符显示,其中顶点显示两边. 题解:题意的理解是难点,题目对图片的范围确定说得有点含糊不清,博主一开始就被出现的五张图片的样例迷惑,理解重心放错了.题目最需要理解的是