vis

【SHOI2006】仙人掌

无人久伴 提交于 2020-01-09 22:30:53
题目链接 分析:   无向仙人掌比较简单。   一个仙人掌首先是个连通图。一遍深搜可以筛掉。   根据定义,如果有任意边被不同的简单环经过,它不是仙人掌。   那么我们现在要对边,计数经过它的环。   这里的做法是树上差分。第一遍深搜还要搞出$DFS$树和倍增数组,遇到非树边记录下来。   $Trick\quad vis$数组设三个状态:出边到达$0$点,这条边作为树边,到达的点改成$1$点;到达$1$点,记录成环,自己变成$2$点;到达$2$点,这条成环边已经被记录过,不用管。   用每个点表示它的“到父边”上的计数,就是在每条成环边的端点上$++$,它们的$LCA$上$-=2$,最后再来一遍深搜或者借助$DFN$序由下往上传标记即可。   这样得到的边上的计数不代表实际有多少个简单环经过它。但一旦出现共边的简单环,一定有边上的计数超过$1$。这就够了。   接下来计算“仙人数”。   既然不能破坏连通性,那么不能剪那些不在简单环上的树边。发现去掉任意简单环上的一条边满足条件。于是答案就很显然了。设有$k$个简单环,第$i$个简单环有$s_i$条边,那么$$ans=\prod\limits_{i=1}^{k}(s_i+1)$$   用$LCA$算$s$值,加上高精度,没了。 实现(100分): #include<iostream> #include<cstdio>

hdu 5656 CA Loves GCD

ⅰ亾dé卋堺 提交于 2020-01-08 09:28:29
CA Loves GCD Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 882 Accepted Submission(s): 305 Problem Description CA is a fine comrade who loves the party and people; inevitably she loves GCD (greatest common divisor) too. Now, there are N different numbers. Each time, CA will select several numbers (at least one), and find the GCD of these numbers. In order to have fun, CA will try every selection. After that, she wants to know the sum of all GCDs. If and only if there is a number exists in a selection, but does not exist in another one,

hdu5521 Meeting

偶尔善良 提交于 2020-01-08 00:45:48
Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 421 Accepted Submission(s): 136 Problem Description Bessie and her friend Elsie decide to have a meeting. However, after Farmer John decorated his fences they were separated into different blocks. John's farm are divided into n blocks labelled from 1 to n . Bessie lives in the first block while Elsie lives in the n -th one. They have a map of the farm which shows that it takes they t i minutes to travel from a block in E i to another block in E i where E i ( 1 ≤ i ≤ m ) is a set of blocks.

一个技巧———把符合某种情况的数据存到容器中

天涯浪子 提交于 2020-01-07 08:53:42
刷题以后要及时总结,看看别人的代码来让自己提高。总结一些实现某个功能的小算法,以便于以后要用的时候很快能敲出来。 比如说,要把数组里没有出现的数字存到某个容器里。 选择数组: 1 int a[maxn]; 2 int vis[maxn]; 3 int n; 4 cin>>n; 5 for(int i=1;i<=n;i++){ 6 cin>>a[i]; 7 if(a[i]) vis[a[i]]=true; 8 } 9 int idx=0; 10 for(int i=n;i>=1;i--){ 11 if(!vis[i]){ 12 b[idx++]=i; 13 } 14 } 15 View Code 来源: https://www.cnblogs.com/wjstmdq/p/12153943.html

tarjan缩点+dag上dp

旧时模样 提交于 2020-01-06 22:05:30
题目描述 给定一个 n个点 mm条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。 输入格式 第一行两个正整数 n,m 第二行 n个整数,依次代表点权 第三至 m+2 行,每行两个整数 u,v,表示一条 u→v 的有向边。 输出格式 共一行,最大的点权之和。 输入输出样例 输入 #1 2 2 1 1 1 2 2 1 输出 #1 2 #include < cstdio > #include < cstring > #include < algorithm > #include < cmath > using namespace std ; const int maxn = 100005 ; int n , m ; int head [ maxn ] , tot ; int dfn [ maxn ] , low [ maxn ] , Stack [ maxn ] , sum [ maxn ] , belong [ maxn ] , top , ans , cnt ; int x [ maxn ] , y [ maxn ] , w [ maxn ] , dis [ maxn ] ; bool vis [ maxn ] ; struct node { int to , next

素数筛两种方法

感情迁移 提交于 2020-01-06 01:15:17
#include <iostream> #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; const int maxn=10005; bool vis[maxn]; int prime[maxn]; void make_prime()//一般线性筛,会出现重复筛,每一次筛掉的是素数的倍数 { memset(vis,true,sizeof(vis)); vis[0]=vis[1]=false; int tot=0; for(int i=2;i<maxn;i++) { if(vis[i])//表明i是素数 { prime[++tot]=i; for(int j=i*i;j<maxn;j+=i)//将能够整除这个数的筛掉 vis[j]=false; } } } void Euler_prime()//快速线性筛法,每一次筛掉的是i*(小于它最小素因子)的合数 { memset(vis,true,sizeof(vis)); int tot=0; for(int i=2;i<maxn;i++) { if(vis[i]) prime[tot++]=i; for(int j=0;j<tot&&prime[j]*i<maxn;j++)/

Assignment 【HDU - 2853】【KM算法+思维】

半城伤御伤魂 提交于 2020-01-04 03:22:23
题目链接 这个思维,当真是有点想不到,一开始净是往link_x[]这个角度去想了,但是这样的话,又会影响KM形成的交错树,显然不是这么解的。 题意 :有N个公司,还有M个任务,任务数大于等于公司数,然后每家公司做每个任务都有对应的贡献,于是乎,初始在加上每个公司有原本应该做的任务,就有一个初始贡献,现在我们想要最少的改变公司和对应的做的任务,想知道最大可以改变的值是多少? 思路 :首先,改KM板子的话,我自认为没这个实力,然后的话,这题的突破口在于是否要修改这个问题上面。然后,初略看了他人的解法主要是有个 放大 。为什么要放大?我想了想,一共我们要取N个任务,那么,如果给每个值都放大成K倍(K > N)的话,我们再考虑每个原来的值(假定给原来的每个初定任务都“+1”贡献),我们如果全部选择的是初始条件的话,它除以K之后的答案是不变的。并且,如果有换的话,证明一点,换的方向肯定是比它更优的,于是这个K倍就引刃而解了! 说实话,这是个天才的游戏——K倍,真的很有趣。 #include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include

leetcode130

心不动则不痛 提交于 2020-01-03 18:24:23
class Solution { public: int dx[4] = {0,-1,0,1}; int dy[4] = {-1,0,1,0}; void solve(vector<vector<char>>& board) { if(board.empty()) return; vector<vector<bool>>vis(board.size(),vector<bool>(board[0].size(),0)); for(int i = 0;i<board.size();i++) { dfs(i,0,board,vis); dfs(i,board[i].size()-1,board,vis); } for(int j = 0;j<board[0].size();j++) { dfs(0,j,board,vis); dfs(board.size()-1,j,board,vis); } for(int i = 0;i<board.size();i++) { for(int j = 0;j<board[i].size();j++) { if(board[i][j] == 'A') board[i][j] = 'O'; else board[i][j] = 'X'; } } } void dfs(int x,int y,vector<vector<char>>& board

Mining Station on the Sea 【HDU - 2448】【KM算法+多源最短路】

我们两清 提交于 2020-01-01 16:51:06
题目链接 题意 : 给你N个港口,有N艘船,它们分别在不同的矿厂,现在呢,它们要返回港口了,并且每个港口只能停靠一只船,而且呢船只要到了港口就不可以再往外跑了。现在给出K条边,是矿厂与矿厂之间的无向路径,然后呢有P条边,是港口与矿厂之间的无向路径。 思路 : 在这里,我们需要把“进了港口就不能再出来了”这个关键点用好,我们肯定可以确定的是船只能在矿厂和矿厂之间移动,所以我们不妨让起点变成港口,并且再也没有港口的边了,我们直接让它们在矿厂与矿厂之间跑,就可以使得它们确定与该港口之间的最短路了,然后跑KM算法的最小权完美匹配(负边)。即可。 #include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #include <unordered_map> #include <unordered_set> #define lowbit(x) ( x&(-x) ) #define pi 3.141592653589793 #define

LeetCode 169周赛

白昼怎懂夜的黑 提交于 2020-01-01 02:40:29
Leetcode 169周赛 DFS关了,没剪枝,疯狂TLE 难顶啊!!!11点才开始做的,第四题一看数据这么少,铁暴力做啊!写完就TLE了,然后,就没有然后了,12点到了,真是弱鸡啊!先挂前三道题答案吧! A: 和为零的N个唯一整数 题目大意: 给定整数n,返回n个不同整数组成的数组,要求和为0; 解题思路: 围绕0对称输出即可。 送分题 代码展示: class Solution { public : vector < int > sumZero ( int n ) { vector < int > ans ; if ( n % 2 ) { ans . push_back ( 0 ) ; for ( int i = 1 ; i <= n / 2 ; i ++ ) ans . push_back ( i ) , ans . push_back ( - i ) ; } else for ( int i = 1 ; i <= n / 2 ; i ++ ) ans . push_back ( i ) , ans . push_back ( - i ) ; return ans ; } } ; B: 两棵二叉搜索树中的所有元素 题目大意: 给定两棵二叉搜索树,返回包含两棵树所有整数的升序列表。 解题思路: 解法一:简单思路,遍历两棵二叉树,然后排序,时间复杂度 O ( ( n + m )