拓扑排序 codevs 4040 cojs 438

codevs 4040 EZ系列之奖金

时间限制: 1 s

空间限制: 64000 KB

题目等级 : 钻石 Diamond

题目描述 Description

由于无敌的WRN在2015年世界英俊帅气男总决选中胜出,EZ总经理Mr.Lin心情好,决定给每位员工发奖金。EZ决定以每个人本年在EZ的贡献为标准来计算他们得到奖金的多少。

于是Mr.Lin下令召开m方会谈。每位参加会谈的代表提出了自己的意见:“我认为学生a的奖金应该比b高!”Mr.Lin决定要找出一种奖金方案,满足各位代表的意见,且同时使得总奖金数最少。每位学生奖金最少为100元。

输入描述 Input Description

第一行两个整数n,m,表示学生总数和代表数;

以下m行,每行2个整数a,b,表示某个代表认为第a号学生奖金应该比第b号学生高。

输出描述 Output Description

若无法找到合法方案,则输出“-1”;否则输出一个数表示最少总奖金。

样例输入 Sample Input

2 1

1 2

样例输出 Sample Output

201

数据范围及提示 Data Size & Hint

80%的数据满足n<=1000,m<=2000;

100%的数据满足n<=10000,m<=20000。

 1 #include<iostream>
 2 #define inf (1<<31)-1
 3 using namespace std;
 4 #include<cstdio>
 5 typedef long long ll;
 6 #include<cstring>
 7 #define N 10010
 8 #include<stack>
 9 stack<int>sta;
10 struct Edge{
11     int v,last;
12 }edge[N<<1];
13 ll ans=0;
14 int indu[N],head[N],t=0,u,tot=0,v,n,m;
15 void add_edge(int u,int v)
16 {
17     ++t;
18     edge[t].v=v;
19     edge[t].last=head[u];
20     head[u]=t;
21 }
22 int read()
23 {
24     int sum=0,ff=1;char s;
25     s=getchar();
26     while(s<‘0‘||s>‘9‘)
27     {
28         if(s==‘-‘) ff=-1;
29         s=getchar();
30     }
31     while(‘0‘<=s&&s<=‘9‘)
32     {
33         sum=sum*10+s-‘0‘;
34         s=getchar();
35     }
36     return sum*ff;
37 }
38 void input()
39 {
40     n=read();m=read();
41     for(int i=1;i<=m;++i)
42     {
43         v=read();u=read();
44         add_edge(u,v);
45         indu[v]++;
46     }
47 }
48 bool toposort()
49 {
50     int mon=0;
51     while(tot<n)
52     {
53         for(int i=1;i<=n;++i)
54         {
55             if(!indu[i])
56             {
57                 ans+=100+mon;
58                 sta.push(i);
59                 indu[i]=inf;
60                 tot++;
61             }
62         }
63         if(sta.empty()) return false;
64         while(!sta.empty())
65         {
66             int topt=sta.top();
67             sta.pop();
68             for(int l=head[topt];l;l=edge[l].last)
69             {
70                 indu[edge[l].v]--;
71             }
72         }
73         mon++;
74     }
75     return true;
76 }
77 int main()
78 {
79     input();
80     if(toposort())
81     {
82         cout<<ans<<endl;
83     }
84     else printf("-1\n");
85     return 0;
86 }

cojs 438. 烦人的幻灯片

★☆   输入文件:slides.in   输出文件:slides.out   简单对比
时间限制:1 s   内存限制:128 MB

【问题描述

李教授将于今天下午作一次非常重要的演讲。不幸的是他不是一个非常爱整洁的人,他把自己演讲要用的幻灯片随便堆在了一起。因此,演讲之前他不得不去整理这些幻灯片。做为一个讲求效率的学者,他希望尽可能简单地完成它。教授这次演讲一共要用n张幻灯片(n≤26),这n张幻灯片按照演讲要使用的顺序已经用数字l,2,…,n在上面编了号。因为幻灯片是透明的,所以我们不能一下子看清每一个数字所对应的幻灯片。
现在我们用大写字母A,B,C,…再次把幻灯片依次编号。你的任务是编写一个程序,把幻灯片的数字编号和字母编号对应起来,显然这种对应应该是惟一的;若是出现多种对应的情况或是某些数字编号和字母编号对应不起来,我们就称对应是无法实现的。

输入格式】

幻灯片的情况通过一个文本文件slides.in输入。

文件的第1行只有一个整数n,表示有n张幻灯片,接下来的n行每行包括4个整数Xmin,Xmax,Ymin,Ymax(整数之间用空格分开)为幻灯片的坐标,这n张幻灯片按其在输入文件中出现的顺序从前到后依次编号为A,B,C,…
再接下来的n行依次为n个数字编号的坐标x,y,显然在幻灯片之外是不会有数字的。

输出格式】

要求将程序的运行结果写入一个名为slides.out的文本文件。若是对应可以实现,输出文件应该包括n行,每一行为一个字母和一个数字,中间以一个空格隔开,并且各行以字母的升序排列,注意输出的字母要大写并且顶格;反之,若是对应无法实现,在文件的第1行顶格输出None即可。行首行末并无多余的空格。

输入输出样例】
输 入
4
6 22 10 20
4 18 6 16
8 20 2 18
10 24 4 8
9 15
19 17
11 7
21 11
输 出
A 4
B 1
C 2
D 3

这道题目类似于拓扑排序的思想:

 1 #define N 30
 2 #include<vector>
 3 #include<iostream>
 4 using namespace std;
 5 #include<cstdio>
 6 #include<algorithm>
 7 struct Edge{
 8     int u;
 9     vector<int>a;
10     bool operator <(const Edge&p)
11     const{return a.size()<p.a.size();}
12 }bh[N];
13 struct Kp{
14     int x1,x2,y1,y2;
15 }kp[N];
16 int flag[N],t=0,tot=0,n;
17 void input()
18 {
19     scanf("%d",&n);
20     for(int i=1;i<=n;++i)
21     {
22         scanf("%d%d%d%d",&kp[i].x1,&kp[i].x2,&kp[i].y1,&kp[i].y2);
23     }
24 //    memset(flag,0,sizeof(flag));
25 }
26 void add_edge(int u,int v)
27 {
28     bh[u].u=u;
29     bh[u].a.push_back(v);
30 }
31 void add()
32 {
33     int xi,xa,yi,ya;
34     for(int i=1;i<=n;++i)
35     {
36         scanf("%d%d",&xi,&yi);
37         for(int j=1;j<=n;++j)
38         {
39             if(xi>=kp[j].x1&&xi<=kp[j].x2&&yi>=kp[j].y1&&yi<=kp[j].y2)
40             {
41                 add_edge(i,j);
42             }
43         }
44     }
45 }
46 int main()
47 {
48     freopen("slides.in","r",stdin);
49     freopen("slides.out","w",stdout);
50     input();
51     add();
52     sort(bh+1,bh+n+1);
53     for(int i=1;i<=n;++i)
54     {
55         for(int j=0;j<bh[i].a.size();++j)
56         {
57             if(flag[bh[i].a[j]]==0)
58             {
59                 int temp=bh[i].a[j];
60                 flag[bh[i].a[j]]=bh[i].u;
61                 tot++;
62                 break;
63             }
64         }
65     }
66     int tbflag[N]={0};
67     for(int i=1;i<=n;++i)
68     {
69         for(int j=bh[i].a.size()-1;j>=0;--j)
70         {
71             if(tbflag[bh[i].a[j]]==0)
72             {
73                 int temp=bh[i].a[j];
74                 tbflag[bh[i].a[j]]=bh[i].u;
75                 break;
76             }
77         }
78     }
79     bool fla=true;
80     for(int i=1;i<=n;++i)/*再反着做一次,是确保结果唯一的*/
81     {
82         if(tbflag[i]!=flag[i])
83         {
84             fla=false;break;
85         }
86     }
87     if(tot==n&&fla)
88     {
89         for(int i=1;i<=n;++i)
90         {
91             printf("%c %d\n",i+‘A‘-1,flag[i]);
92         }
93     }
94     else {
95         printf("None\n");
96     }
97     fclose(stdin);fclose(stdout);
98     return 0;
99 }
时间: 2024-10-18 10:14:05

拓扑排序 codevs 4040 cojs 438的相关文章

NOIP 车站分级 (luogu 1983 &amp; codevs 3294 &amp; vijos 1851) - 拓扑排序 - bitset

描述 一条单向的铁路线上,依次有编号为 1, 2, ..., n 的 n 个火车站.每个火车站都有一个级别,最低为 1 级.现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车站 x,则始发站.终点站之间所有级别大于等于火车站 x 的都必须停靠.(注意:起始站和终点站自然也算作事先已知需要停靠的站点)例如,下表是 5 趟车次的运行情况.其中,前 4 趟车次均满足要求,而第 5 趟车次由于停靠了 3 号火车站(2 级)却未停靠途经的 6 号火车站(亦为 2 级)而不满足要求

【拓扑排序】CODEVS 2833 奇怪的梦境

拓扑排序模板. 1 #include<cstdio> 2 #include<vector> 3 #include<stack> 4 using namespace std; 5 #define N 10001 6 vector<int>G[N]; 7 stack<int>S; 8 int n,m,x,y,ru[N],tot; 9 int main() 10 { 11 scanf("%d%d",&n,&m); 1

拓扑排序讲解

在这里我们要说的拓扑排序是有前提的 我们在这里说的拓扑排序是基于有向无环图的!!!. (⊙o⊙)…我所说的有向无环图都知道是什么东西吧.. 如果不知道,我们下面先来来说说什么是有向无环图. 所谓有向无环图,顾名思义是不存在环的有向图(至于有向图是什么不知道的在前面我们有一个图论讲解上都有). 点的入度:以这个点为结束点的边数. 点的出度:以这个点为出发点的边的条数. 拓扑序就是对于一个节点的一个排列,使得(u,v)属于E,那么u一定出现在v的前面.然而拓扑排序就是一个用来求拓扑序的东西. 对于左

CSU 1804: 有向无环图(拓扑排序)

http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1804 题意:…… 思路:对于某条路径,在遍历到某个点的时候,之前遍历过的点都可以到达它,因此在这个时候对答案的贡献就是∑(a1 + a2 + a3 + ... + ai) * bv,其中a是之前遍历到的点,v是当前遍历的点. 这样想之后就很简单了.类似于前缀和,每次遍历到一个v点,就把a[u]加给a[v],然后像平时的拓扑排序做就行了. 1 #include <bits/stdc++.h>

7-9-有向图无环拓扑排序-图-第7章-《数据结构》课本源码-严蔚敏吴伟民版

课本源码部分 第7章  图 - 有向无环图拓扑排序 ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接??? <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明        课本源码合辑  链接??? <数据结构>课本源码合辑        习题集全解析  链接??? <数据结构题集>习题解析合辑        本源码引入的文件  链接? Status.h.SequenceStack.c.ALGraph.c    

hihoCoder 1175:拓扑排序二

题目链接: http://hihocoder.com/problemset/problem/1175 题目难度:一星级(简单题) 今天闲来无事,决定刷一道水题.结果发现这道水题居然把我卡了将近一个钟头. 最后终于调通了.总结起来,原因只有一个:不够仔细. 思路不用细说了,就是拓扑排序的简单应用.然而,一些不起眼的细节才是让你掉坑里的真正原因. 猜猜哪儿可能出bug? // A simple problem, but you can't be too careful with it. #inclu

hdu1285(拓扑排序)

这道题要求没有输赢关系的两个元素必须按照升序输出,有输赢关系的,赢得在输的前面,所以用队列或者栈来降低时间复杂度的优化过的拓扑排序会出错. 比如这组输入 5 3 1 2 2 3 4 5 至少我写的两种拓扑排序都wa了.但是不用队列或者栈来优化的话, 1.每次都从头至尾扫描一遍,找到一个没标记过的节点, 2.将它标记 3.然后删除从它出来的每条边. 重复这三个操作,加标记的次序,就是题目要的答案. 下面的代码中用到了队列,但只是用来保存答案而已.并没有用它优化的意思. #include <iost

uva 10305 Ordering Tasks(拓扑排序)

拓扑排序,不用判断是否有环,dfs挺简单的 代码: #include<stdio.h> #include<string.h> #include<stdlib.h> int map[105][105]; int visit[105]; int c[105]; int n,m,t; void dfs(int x) { visit[x] = 1; for(int i=1; i<=n; i++) { if(!visit[i]&&map[i][x]==1)

NOJ 2015年陕西省程序设计竞赛网络预赛(正式赛)(忙碌的选课系统-拓扑排序注意重边)

D - 忙碌的选课系统 Time Limit: 10000 ms        Memory Limit: 65536 KB Submit Description 每学期末,都是万众瞩目的选课时间,由于人数过多,某学校的服务器常常被无数的学生挤的爆掉,这是,教务系统大人说,你们选个课都这么慢,居然还怪我们.于是,每次教务系统都会在服务器快要瘫痪前关闭它.在无数学生的强烈抗议下,教务系统妥协了,再给每个人一次机会,但他让我们用最快的方式决定该选的课程,选上后就退出. 这让大一学渣狗犯了难,在新的选