CSU 1802 小X的战斗力【拓扑dp】

题目链接

题意:n个人,每个人有一个能力值。给出m组关系A, B, 表示A的能力值大于B的能力值。

问:m组关系中是否有自相矛盾的?若不矛盾,问:第1个人在所有人的能力值中排名第几?有多少人的能力值的排名可以确定?

题解:拓扑排序。存两个图,原图与反图。

若原图可达该点数+反图可达该点数-1 = n,则排名确定。

bitset一下。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define X first
 4 #define Y second
 5 #define pii pair<int, int>
 6 #define mp make_pair
 7 typedef long long ll;
 8
 9 vector<int> ve[155], rve[155];
10 int in[155], rin[155];
11 bitset<155> dp[155], rdp[155];
12 int ra[155], rra[155];
13 int topsort(int n, int* in, vector<int>* ve, bitset<155>* dp, int* ra){
14     queue<int> Q;
15     for(int i = 1; i <= n; i++)
16         if(in[i] == 0) Q.push(i);
17     int ret = 0;
18     while(!Q.empty()){
19         int p = Q.front();
20         Q.pop();
21         ret++;
22         ra[p] = ret;
23         for(int i = 0; i < ve[p].size(); i++){
24             int to = ve[p][i];
25             in[to]--;
26             dp[to] |= dp[p];
27             if( !in[to] ) Q.push(to);
28         }
29     }
30     return ret == n;
31 }
32 void debug(int n){
33     puts("*******************");
34     for(int i = 1; i <= n; i++){
35         cout << i << endl;
36         cout << dp[i] << ‘ ‘ << rdp[i] << endl;
37     }
38     puts("********end********");
39 }
40 int main(){
41     int t; scanf("%d", &t);
42     while(t--){
43         int n, m, u, v;
44         scanf("%d%d", &n, &m);
45         for(int i = 1; i <= n; i++){
46             ve[i].clear();
47             rve[i].clear();
48             in[i] = rin[i] = 0;
49             ra[i] = rra[i] = 0;
50             dp[i].reset(), rdp[i].reset();
51             dp[i][i-1] = rdp[i][i-1] = 1;
52         }
53         for(int i = 0; i < m; i++){
54             scanf("%d%d", &u, &v);
55             ve[u].push_back(v);
56             in[v]++;
57             rve[v].push_back(u);
58             rin[u]++;
59         }
60
61         if( !topsort(n, in, ve, dp, ra) )//有向图有环
62             puts("Wrong");
63         else{
64             topsort(n, rin, rve, rdp, rra);
65             //前面有 dp[i]-1 个, 后面有 rdp[i]-1 个;
66             printf("%d\n", dp[1].count()+rdp[1].count()-1 == n? ra[1]:-1);
67             int sum = 0;
68             for(int i = 1; i <= n; i++)
69                 if(dp[i].count()+rdp[i].count()-1 == n) sum++;
70             printf("%d\n", sum);
71         }
72     }
73     return 0;
74 }

时间: 2024-10-12 22:57:30

CSU 1802 小X的战斗力【拓扑dp】的相关文章

【BZOJ1179】【Apio2009】Atm 强连通分量缩点+拓扑DP/拓扑最长路 kosaraju+tarjan+dfs转非递归三种代码

题解: 首先第一个阶段, 可以写kosaraju.也可以写tarjan. 这两种还都分递归和dfs转非递归. ----------------------------------四种方案. 第二个阶段,可以写拓扑DP 也可以写最长路 ----------------------------------乘上之前的,,八种方案. 本文写了kosaraju递归版,tarjan递归版,kosaraju非递归版. --只怪学校oj系统栈太小..都是逼得啊. 代码1(tarjan): #include <c

UVA 11324.The Largest Clique tarjan缩点+拓扑dp

题目链接:https://vjudge.net/problem/UVA-11324 题意:求一个有向图中结点数最大的结点集,使得该结点集中任意两个结点u和v满足:要目u可以到达v,要么v可以到达u(相互可达也可以). 思路:同一个强联通分量中满足结点集中任意两个结点u和v满足:要目u可以到达v,要么v可以到达u(相互可达也可以).把强联通分量收缩点后得到scc图,让每个scc结点的权值等于他的结点数,则求scc图上权最大的路径.拓扑dp,也可以直接bfs,但是要建立一个新的起点,连接所有入度为0

【BZOJ1093】【ZJOI2007】最大半联通子图 [拓扑][DP][Tarjan]

最大半连通子图 Time Limit: 30 Sec  Memory Limit: 162 MB[Submit][Status][Discuss] Description 一个有向图G=(V,E)称为半连通的(Semi-Connected): 如果满足:∀u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径. 若G'=(V',E')满足V'∈V,E'是E中所有跟V'有关的边,则称G'是G的一个导出子图. 若G'是G的导出子图,且G'半连通,则称

HLG 1813 小乐乐要下山 (dp)

链接: http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1813 Description 上学的路总是那么艰辛,在小乐乐辛苦的出了家门之后,她才想起自己的家已经搬到山上了(睡的真迷糊).下山的路同样十分艰难,不同的地方通行的难易程度也不同.如图所示,小乐乐现在在山顶上,她面前有两条路,每条路通往一个地点,每个地点有一个值,表示这个通行的难易程度.最底层的地点就是山脚了.大家知道,小乐乐好懒好懒

BZOJ3437:小P的牧场(DP+斜率优化)

小P的牧场[题目描述]背景:小P 是个特么喜欢玩MC 的孩纸...小P 在MC 里有n 个牧场,自西向东呈一字形排列(自西向东用1…n 编号),于是他就烦恼了:为了控制这n 个牧场,他需要在某些牧场上面建立控制站,每个牧场上只能建立一个控制站,每个控制站控制的牧场是它所在的牧场一直到它西边第一个控制站的所有牧场(它西边第一个控制站所在的牧场不被控制)(如果它西边不存在控制站,那么它控制西边所有的牧场),每个牧场被控制都需要一定的花费(毕竟在控制站到牧场间修建道路是需要资源的嘛~),而且该花费等于

小明的密码-初级DP解法

#include #include #include using namespace std; int visited[5][20][9009];// 访问情况 int dp[5][20][9009]; // M N num num即M-1位的数字 int num_2[7]= {2,3,5,7,11,13,17}; int num_3[9]= {2,3,5,7,11,13,17,19,23}; int num_4[11]= {2,3,5,7,11,13,17,19,23,29,31}; //存储

POJ 3249 拓扑+dp

Test for Job Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 9479   Accepted: 2168 Description Mr.Dog was fired by his company. In order to support his family, he must find a new job as soon as possible. Nowadays, It's hard to have a job

HDU2067 小兔的棋盘【DP】

小兔的棋盘 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6922    Accepted Submission(s): 3708 Problem Description 小兔的叔叔从外面旅游回来给她带来了一个礼物,小兔高兴地跑回自己的房间,拆开一看是一个棋盘,小兔有所失望.不过没过几天发现了棋盘的好玩之处.从起点(0,0)走到终点(

【BZOJ 4665】 4665: 小w的喜糖 (DP+容斥)

4665: 小w的喜糖 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 94  Solved: 53 Description 废话不多说,反正小w要发喜糖啦!! 小w一共买了n块喜糖,发给了n个人,每个喜糖有一个种类.这时,小w突发奇想,如果这n个人相互交换手中的糖,那会有多少种方案使得每个人手中的糖的种类都与原来不同. 两个方案不同当且仅当,存在一个人,他手中的糖的种类在两个方案中不一样. Input 第一行,一个整数n 接下来n行,每行一个整数