首页 > 其他分享 >P2341 [USACO03FALL / HAOI2006] 受欢迎的牛 G

P2341 [USACO03FALL / HAOI2006] 受欢迎的牛 G

时间:2024-05-09 12:03:55浏览次数:19  
标签:sccno int ++ HAOI2006 num P2341 USACO03FALL include low

链接:https://www.luogu.com.cn/problem/P2341
题目:
思路:
tarjan缩点:把所有强连通分量缩成一个点,然后统计出度为0的缩点,如果只有一个,那么能成为明星的数量就是该缩点扩充后的个数;如果不止一个,那就是0.
代码:
额,就是不知道为什么debug了两节课.......

#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<cmath>
#include<limits.h>
#include<climits>
#include<fstream>
#include<set>
typedef long long ll;
using namespace std;
const int N = 1e4 + 5;
int cnt;
int  low[N], num[N], dfn;
int sccno[N], stack[N], top;
int cd[N];
int countt[N];
vector<int>G[N];
void dfs(int u)//tarjan 的 dfs板子
{
	stack[top++] = u;
	low[u] = num[u] = ++dfn;
	for (int i = 0; i < G[u].size(); i++)
	{
		int v = G[u][i];
		if (!num[v])
		{
			dfs(v);
			low[u] = min(low[u], low[v]);//注意
		}
		else if (!sccno[v]) low[u] = min(low[u], num[v]);
	}
	if (num[u] == low[u])
	{
		cnt++;
		while (1)
		{
			int v = stack[--top];
			sccno[v] = cnt;
			countt[cnt]++;
			if (u == v)break;
		}
	}

}
bool jd = false;
void tarjan(int n)
{
	cnt = dfn = top = 0;
	memset(low, 0, sizeof(low));
	memset(num, 0, sizeof(num));
	memset(sccno, 0, sizeof(sccno));

	for (int i = 1; i <= n; i++)
		if (!num[i])
			dfs(i);
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	int n, m, u, v;
	cin >> n >> m;
	for (int i = 0; i < m; i++)
	{
		cin >> u >> v;
		G[u].push_back(v);
	}
	tarjan(n);
	//统计:如果只有一个sccno的出度为0,那么就是该sccno的数量;如果有大于1个,那么肯定不行
	//如何统计scc的出度?直接判断每个scc的点,如果子节点有通往另一个度的,跳过,否则继续;
	map<int, bool>each_scc;
	for (int i = 1; i <= n; i++)
	{
		for (int j = 0; j < G[i].size(); j++)
		{
			if (sccno[G[i][j]] != sccno[i])
				cd[sccno[i]]++;
		}
	}
	int cnttt = 0,rec;
	for (int i = 1; i <= cnt; i++)
	{
		if (!cd[i]) { cnttt++; rec = i; }
	}
	if (cnttt == 0)cout << n;
	else if (cnttt >= 2)cout << 0;
	else cout << countt[rec];


	return 0;
}

标签:sccno,int,++,HAOI2006,num,P2341,USACO03FALL,include,low
From: https://www.cnblogs.com/zzzsacmblog/p/18181810

相关文章

  • 解题报告P2501 [HAOI2006] 数字序列
    P2501[HAOI2006]数字序列题目描述现在我们有一个长度为\(n\)的整数序列\(a\)。但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列。但是不希望改变过多的数,也不希望改变的幅度太大。输入格式第一行是一个整数,表示序列长度\(n\)。第二行有\(n\)个整数,第\(......
  • P2341 受欢迎的牛 G 题解
    LinkP2341[USACO03FALL/HAOI2006]受欢迎的牛GQuestion牛栏中有\(N\)头奶牛,和一些\(M\)对爱慕关系,A->B表示A爱慕B。每个奶牛都喜欢自己,被所有奶牛喜欢就是一头明星奶牛,求明星奶牛的数量Solution考虑一个强连通分量里面的奶牛是相互爱慕的,先根据强连通分量缩点,缩......
  • 洛谷P2341 [USACO03FALL] 受欢迎的牛 G
    P2341受欢迎的牛G题解这题我们需要了解强连通分量一、定义在有向图\(G\)中,如果两个顶点\(u\),\(v\)间有一条从\(u\)到\(v\)的有向路径,同时还有一条从\(v\)到\(u\)的有向路径,则称两个顶点强连通。如果有向图\(G\)的每两个顶点都强连通,称\(G\)是一个强连通......
  • P2501 [HAOI2006] 数字序列
    先来看第一问。发现直接做要考虑两数中间的数能否变得合法,所以按套路将\(a_i\)减去\(i\),这样就只要变成单调不降,只要两数合法中间的数就一定能变得合法。考虑不改变的那些数,它们一定单调不降,所以答案就是序列总长度减去最长不下降子序列的长度。接下来看第二问,尝试观察一些性......
  • P2501 [HAOI2006] 数字序列
    原题是思路非常值得学习的一道题第一问:首先我们感性上觉得这题应该和LIS有一点关系,但里面有一点问题:1750505018如果我们求LIS的话,我们会认为只需要改掉505050即可,但其实我们只改掉这些数,我们是无法做到让数单增的我们发现这个限制写成数学语言即为:\(a_i-a_j\geq......
  • [刷题笔记] Luogu P2340 [USACO03FALL] Cow Exhibition G
    ProblemSolution乍看可能没有思路。我们注意到本题是牵扯到一头奶牛选or不选的问题,非常自然地想到01背包。接下来我们就尝试将本题背景转换成01背包问题。我们可以将智商转换成容量,情商转换成价值。(当然反过来也可)然后就可以套用01背包板子了:\[f_{i,j}=min(f_{i-1,j},f_{i-1......
  • 洛谷P2341/USACO03FALL 受欢迎的牛
    题意分析题目链接喜欢是单向的,喜欢有传递性……Emmm这听起来好像……对了,就是连通性问题!我们不妨将奶牛之间的喜欢关系表示为一条条单向边,怎么求明星奶牛的数量呢?这里......
  • 缩点-DAG 性质的应用:P2002,P1262,P2341,P1407,P2746(P2812)
    缩点不只用于转化图为DAG,还可以进一步发掘图的性质,从而将题目变成结论题所求信息转化到图上,方便建模。P2002https://www.luogu.com.cn/problem/P2002在一个强连通分量......
  • P2341 [HAOI2006] 受欢迎的牛 G
    每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的问有多少头奶牛可以当明星 缩点......
  • 洛谷 P2501 [HAOI2006]数字序列
    洛谷P2501[HAOI2006]数字序列第一问实质是最大化不修改的数。假设\(i,j\)不修改(\(j<i\)),那么必须满足\(a_i-a_j\geqi-j\)。移项:\(a_i-i\geqa_j-j\)。设\(b_i=a......