Gym 100801G Graph 拓扑排序

http://codeforces.com/gym/100801/attachments

用set维护一下入度为零的点,每次将当前指针和下一个指针连一条边

写博客只是为了纪念一下第一次用set,还有我逝去的4小时青春

PS.iterator在迭代器中不要xjb改

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
int n,m,k;
set<int>s;
int f[200000],g[200000];
int sum[200000],tot,sedge;
struct point
{
    int to,next;
}e[10000000];
void add(int x,int y)
{
    e[++tot].to=y;
    e[tot].next=g[x];
    g[x]=tot;
}
int main()
{
    freopen("graph.in","r",stdin);
    freopen("graph.out","w",stdout);
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        sum[y]++;
    }
    for(int i=1;i<=n;i++)
    {
        if(sum[i]==0)
        s.insert(i);
    }//cout<<"!!!!!!"<<endl;
    int sk=k;
    for(int p=1;p<=n;p++)
    {
        int flag=1;
        set<int>::iterator itlast=s.end();itlast--;//cout<<"!!!!!!"<<endl;
        set<int>::iterator itar;
        //cout<<*itlast<<endl;
        for(set<int>::iterator it=s.begin();it!=itlast;it++)
        {//cout<<"!!!!!!"<<endl;
            //cout<<*it<<endl;
            if(f[*it])
            {
                set<int>::iterator tmp=it;
                tmp++;
                f[*it]=*tmp;
                add(*tmp,*it);
                sum[*it]++;
                continue;
            }
            if(f[*it]==0&&sk>0)
            {
                set<int>::iterator tmp=it;
                tmp++;
                f[*it]=*tmp;
                //cout<<*tmp<<" "<<*it<<endl;
                add(*tmp,*it);
                sum[*it]++;//cout<<"!!!!!!"<<endl;
                sk--;
                continue;
            }
            printf("%d ",*it);
            itar=it;
            flag=0;
            break;
        }
        if(flag)
        {
            set<int>::iterator itlast=s.end();itlast--;
            printf("%d ",*itlast);
            int x=*itlast;
            s.erase(s.begin(),s.find(x));
            s.erase(x);
            for(int temp=g[x];temp;temp=e[temp].next)
            {
                sum[e[temp].to]--;
                if(sum[e[temp].to]==0)
                s.insert(e[temp].to);
            }
        }
        else
        {
            int x=*itar;
            s.erase(s.begin(),s.find(x));
            s.erase(x);
            for(int temp=g[x];temp;temp=e[temp].next)
            {
                sum[e[temp].to]--;
                if(sum[e[temp].to]==0)
                s.insert(e[temp].to);
            }
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        if(f[i])ans++;
    }
    cout<<endl<<ans<<endl;
    for(int i=1;i<=n;i++)
    if(f[i])printf("%d %d\n",f[i],i);
    return 0;
}
时间: 2024-08-05 07:04:03

Gym 100801G Graph 拓扑排序的相关文章

hdu-5695 Gym Class(贪心+拓扑排序)

题目链接: Gym Class Time Limit: 6000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Others) Problem Description 众所周知,度度熊喜欢各类体育活动. 今天,它终于当上了梦寐以求的体育课老师.第一次课上,它发现一个有趣的事情.在上课之前,所有同学要排成一列, 假设最开始每个人有一个唯一的ID,从1到N,在排好队之后,每个同学会找出包括自己在内的前方所有同学的最小ID,作为

【CodeForces】915 D. Almost Acyclic Graph 拓扑排序找环

[题目]D. Almost Acyclic Graph [题意]给定n个点的有向图(无重边),问能否删除一条边使得全图无环.n<=500,m<=10^5. [算法]拓扑排序 [题解]找到一个简单环,则欲删除的边一定经过该环.尝试环上的每一条边(至多n条边)后再次拓扑排序判断全图是否有环. 拓扑排序后定位到简单环:剩余图是环+环内DAG,DFS过程中将走入死路的点标-1,访问过标1,找到访问过的点就是简单环.换起始点直到找到环为止. 复杂度O(nm). #include<cstdio>

6081: Gym Class(拓扑排序+优先队列)

6081: Gym Class 时间限制(普通/Java):1000MS/3000MS     内存限制:65536KByte 总提交: 40            测试通过:10 描述 众所周知,度度熊喜欢各类体育活动. 今天,它终于当上了梦寐以求的体育课老师.第一次课上,它发现一个有趣的事情.在上课之前,所有同学要排成一列, 假设最开始每个人有一个唯一的ID,从1到N,在排好队之后,每个同学会找出包括自己在内的前方所有同学的最小ID,作为自己评价这堂课的分数.麻烦的是,有一些同学不希望某个(

Gym - 100801G: Graph (贪心+set+拓扑)(好题)

题意:给定一个N点M边的有向图,叫你加最多K条边,使得最小拓扑序最大. 思路:不是那么简单的题.  参照了别人的代码,最后想通了. 贪心原则: 用两个单调队列维护, 第一个序列S1单增, 表示当前入度为0的点 ; 第二个序列S2单减,表示需要加边的点. 如果S1的最大值大于S2的最大值,则对其加边. #include<bits/stdc++.h> using namespace std; const int maxn=100010; priority_queue<int>p; pr

Gym Class(拓扑排序)

Gym Class Time Limit: 6000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 628    Accepted Submission(s): 244 Problem Description 众所周知,度度熊喜欢各类体育活动.今天,它终于当上了梦寐以求的体育课老师.第一次课上,它发现一个有趣的事情.在上课之前,所有同学要排成一列, 假设最开始每个人有

hiho47 : 拓扑排序&#183;一

时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 由于今天上课的老师讲的特别无聊,小Hi和小Ho偷偷地聊了起来. 小Ho:小Hi,你这学期有选什么课么? 小Hi:挺多的,比如XXX1,XXX2还有XXX3.本来想选YYY2的,但是好像没有先选过YYY1,不能选YYY2. 小Ho:先修课程真是个麻烦的东西呢. 小Hi:没错呢.好多课程都有先修课程,每次选课之前都得先查查有没有先修.教务公布的先修课程记录都是好多年前的,不但有重复的信息,好像很多都不正确了. 小Ho:课程

拓扑排序(Topological Sort)

Graph 拓扑排序(Topological Sort) 假设一个应用场景:你用 C 编写了一个爬虫工具,其中有很多自定义的库:queue.c.queue.h.stack.c.stack.h.heap.c.heap.h 等等,且这些文件没有其他自定义库的依赖:另外还有一些基于上述自定义库的库:bfs.c.bfs.h.dfs.c.dfs.h.dijkstra.c.dijkstra.h.tcpSocket.c.tcpSocket.h 等等:基于以上的库,你开发了一些爬虫程序 scrawlYoutub

【DFS】【拓扑排序】【动态规划】Gym - 100642A - Babs&#39; Box Boutique

给你10个箱子,有长宽高,每个箱子你可以决定哪个面朝上摆.把它们摞在一起,边必须平行,上面的不能突出来,问你最多摆几个箱子. 3^10枚举箱子用哪个面.然后按长为第一关键字,宽为第二关键字,从大到小排序. 如果前面的宽大于等于后面的宽,就连接一条边. 形成一张DAG,拓扑排序后跑最长路即可. #include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespa

2016&quot;百度之星&quot; - 初赛(Astar Round2A)Gym Class(拓扑排序)

Gym Class Accepts: 849 Submissions: 4247 Time Limit: 6000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 众所周知,度度熊喜欢各类体育活动. 今天,它终于当上了梦寐以求的体育课老师.第一次课上,它发现一个有趣的事情.在上课之前,所有同学要排成一列, 假设最开始每个人有一个唯一的ID,从1到NN,在排好队之后,每个同学会找