vis

Codeforces Round #615(Div.3)

£可爱£侵袭症+ 提交于 2020-01-29 15:08:15
Codeforces Round #615(Div.3) A. Collecting Coins 注意(n)可能不够用的情况。 # include <bits/stdc++.h> using namespace std ; # define ll long long const int maxn = 2e5 + 10 ; int main ( ) { ios_base :: sync_with_stdio ( 0 ) ; ll n ; cin >> n ; while ( n -- ) { int a , b , c , n ; cin >> a >> b >> c >> n ; int ma = max ( a , max ( b , c ) ) ; int cnt = abs ( ma - a ) + abs ( ma - b ) + abs ( ma - c ) ; int remain = n - cnt ; if ( remain >= 0 && remain % 3 == 0 ) { cout << "YES" << endl ; } else { cout << "NO" << endl ; } } return 0 ; } B. Collecting Packages 直接模拟这个过程就好了,注意字典序最小的方案。 # include <bits/stdc++.h>

Codeforces Round #615(Div.3)

折月煮酒 提交于 2020-01-29 14:51:55
Codeforces Round #615(Div.3) A. Collecting Coins 注意(n)可能不够用的情况。 # include <bits/stdc++.h> using namespace std ; # define ll long long const int maxn = 2e5 + 10 ; int main ( ) { ios_base :: sync_with_stdio ( 0 ) ; ll n ; cin >> n ; while ( n -- ) { int a , b , c , n ; cin >> a >> b >> c >> n ; int ma = max ( a , max ( b , c ) ) ; int cnt = abs ( ma - a ) + abs ( ma - b ) + abs ( ma - c ) ; int remain = n - cnt ; if ( remain >= 0 && remain % 3 == 0 ) { cout << "YES" << endl ; } else { cout << "NO" << endl ; } } return 0 ; } B. Collecting Packages 直接模拟这个过程就好了,注意字典序最小的方案。 # include <bits/stdc++.h>

Codeforces Round #611 (Div. 3)

て烟熏妆下的殇ゞ 提交于 2020-01-28 01:27:08
F 题意:给你n-1边,n个灯,每个边连着两颗灯,有主,次灯区别,电流由主到次,每条边有一个特性,取消这条边后n个灯不能亮的值(每个灯亮值为2^i,灯编号i),由特性值由大到小给出每条边的主灯,求出每对主灯次灯。 题解:可知是一棵树,排第一个的肯定是原点,即根。然后没出现的肯定是叶子节点,我们遍历一遍求出叶子节点,然后我们知道灯亮与编号有关,所以我们由将叶子节点放入优先队列,叶子节点从小到大与主灯从小到大匹配,当主灯中的cnt【i】为0,说明他已经没有子树,也就是他也是一颗“叶子节点了” 就放入优先队列中继续匹配。 #include<bits/stdc++.h> using namespace std; const int maxn=2e5+10; priority_queue<int,vector<int>,greater<int> >pq; int k,n,x[maxn],vis[maxn],cnt[maxn]; vector<pair<int,int> >G; int main() { cin>>n; int tot=n-1; for(int i=1;i<n;i++){ cin>>x[i]; vis[x[i]]=1; cnt[x[i]]++; } printf("%d\n",x[1]); for(int i=1;i<=n;i++){ if(!vis[i]) pq.push(i

Educational Codeforces Round 80 (Rated for Div. 2) D. Minimax Problem

与世无争的帅哥 提交于 2020-01-26 23:20:06
题目链接 题目意思: n*m的数组, 选取两行,两行合并成一行,取对应位置上的最大值,然后再取这行的最小值。使这个最小值最大,问这两行的行号。 每行的数字最多八个, 思路: 看到每行最多八个数, 就要想到二进制位优化。 首先要二分出来最大的数 x , 对于这个数,我们进行check。 然后对于每一行, 这一行中如果大于 x, 就设为1, 否则就设为 0, 这样每行就可以组成一个数 y 。vis[y] = i; 这个数最大就是256 , 就可以两重for循环,然后暴力判断这两行是不是满足条件。 判断的标准就是 if (vis[i] && vis[j] && (i|j) == (1 << m) - 1) 。 反思: 太巧妙了emmmm # include <bits/stdc++.h> using namespace std ; const int N = 3e5 + 100 ; int a [ N ] [ 10 ] , n , m , ans1 , ans2 ; int vis [ 500 ] ; bool fuck ( int x ) { int tmp ; memset ( vis , 0 , sizeof vis ) ; for ( int i = 1 ; i <= n ; ++ i ) { tmp = 0 ; for ( int j = 1 ; j <= m ; ++ j )

有上下界的网络流问题

不羁岁月 提交于 2020-01-26 20:53:16
有上下界的网络流问题分为无源汇和有源汇两种。 根据周源的《 一种简易的方法求解流量有上下界的网络中网络流问题》 无源汇上下界网络流 的做法是: 设边u->v的下界是B(u,v),上界是C(u,v)。 设M(i)为对于i结点的流入i的下界总和-流出i的下界总和。 增设源点s和汇点t。 如果M(i)>=0 连边s->i,容量为M(i)。 如果M(i)<0 连边i->t,容量为-M(i)。 对于图中的原来的边u-v,连边u->v,容量为C(u,v)-B(u,v)。 然后求最大流。如果对于源点出发的所有边都满流,则说明存在一个可行流满足条件。 有源汇有上下界网络流 的具体做法是: 1.求可行流 从汇点到源点连一条边,容量为INF,其他与无源汇有上下界网络流的建图方法相同。然后以超级源点和超级汇点为网络流的源和汇求一次最大流。 判断起始于超级源点的边是否全部满流即可。 2.求最大流 从汇点到源点连一条边,容量为INF,其他与无源汇有上下界网络流的建图方法相同。然后以超级源点和超级汇点为网络流的源和汇求一次最大流。 判断起始于超级源点的边是否全部满流,若满流,说明存在可行流。 然后去掉汇点到源点连的边,在原来的基础上以原图中的源点和汇点为网络流的源和汇再求一次最大流即可。 ZOJ 2314 Reactor Cooling 无源汇有上下界求最大流 题目链接: http://acm.zju.edu

二分图多重匹配

萝らか妹 提交于 2020-01-26 18:17:11
二分图多重匹配 一般的二分图匹配与多重匹配之间的区别就是: 二分图多重匹配:右边的物品可以和多个左边的相匹配,同时右边的物品可以有一个最大匹配容量V[i] int cnt [ maxn ] , V [ maxn ] ; //cnt[i]记录现在第i个星球有多少个人,V[i]记录i星球的容量 int linker [ maxn ] [ 15 ] ; //linker[i][j]表示第i个星球第j个匹配的人是谁 bool dfs ( int u ) { for ( int i = 1 ; i <= m ; i ++ ) { if ( mapp [ u ] [ i ] && ! vis [ i ] ) //表示第u个人可以匹配第i个星球 { vis [ i ] = 1 ; if ( cnt [ i ] < V [ i ] ) //并且该星球人数未上限,直接匹配 { linker [ i ] [ cnt [ i ] ++ ] = u ; return true ; } for ( int j = 0 ; j < V [ i ] ; j ++ ) { if ( dfs ( linker [ i ] [ j ] ) ) //可以让位置 { linker [ i ] [ j ] = u ; return true ; } } } } return false ; } bool solve ( )

NEFU 栈

。_饼干妹妹 提交于 2020-01-26 10:04:42
基本知识 1、栈的基本性质是先进后出,且只能由栈顶输出。 栈的基本操作 1、初始化栈:stack<数据类型 / 如int、char或结构体名 / >vis / 栈名 / 2、入栈:vis.push(x) 3、出栈:vis.pop() 4、判断是否为空:vis.empty() / 为空返回值为1 / 5、判断栈中元素的数量:vis.size() 6、得到栈顶元素:vis.top() 例题 栈-程序员输入问题 # include <bits/stdc++.h> using namespace std ; int main ( ) { stack < char > vis ; stack < char > vis1 ; char x [ 110 ] , y [ 110 ] , n = 0 ; gets ( x ) ; //字符串的输入带空格 int m = strlen ( x ) ; for ( int i = 0 ; i < m ; i ++ ) { if ( x [ i ] == '@' ) { while ( vis . empty ( ) != 1 ) //判断字符串是否为空 vis . pop ( ) ; continue ; } if ( x [ i ] == '#' ) { if ( vis . empty ( ) != 1 ) { vis . pop ( ) ;

交换棋子

≡放荡痞女 提交于 2020-01-26 06:20:54
  现在除了上下界网络流 和 最小割模型(最大权闭合子图)一类的正确性不会证明 也不是很会用。剩下的比较熟练了。 这几道 都是我精选的好题 觉得 想了很久都没有结果看题解的题目。 题目要求我们 四周相邻的棋子可以交换 但是也同时是在限制次数 最终交换到一个最终状态 。 1. 两个状态 如果黑色棋子和白色棋子个数 不对照的话一定是-1 2. 这道题求最小的次数我们不难想到二分 但是 这个二分没什么用 它跟我们的流量没有任何关系 只跟答案有关 答案跟我们的过程显然联系不大 这个思路弃掉。 3. 那么能够求最小费用 显然就是费用流了 我们把一次交换 想成1费用 最后最小费用最大流就是答案。 4. 此时注意 并非是棋子进行交换而是格子参与交换的次数 是有限制的。 5. 两个棋子进行交换显然我们只需要追究交换出去的那个棋子去了哪里而不是被交换出去的棋子去了哪我们并不关心。这个就是重点了,必须想到这个东西 对于一个从源点出发的流 我们只在意其将要去哪而被交换的东西我们直接忽略。 因为考虑到被交换的棋子一定是不同色的 如果同色那么这个交换将毫无意义不是么也增加了答案的次数所以 被交换的一定是没有用的棋子。 6. 我们不知道是交换进来了还是交换出去了 如果只把一个点拆成两个点的话 我们无法分辨这种情况。 7. 拆成三个点因为一个 从源点 过来的是不占流的 一个 交换进来一个交换出去。 8.

[2016-03-07][UVALive][3212][Crime]

自闭症网瘾萝莉.ら 提交于 2020-01-26 06:19:26
[2016-03-07][UVALive][3212][Crime] 时间:2016-03-06 13:51:13 星期日 题目编号:[UVALive][3212][Crime] 题目大意:端点交替着色黑白,求黑色的最少着色数 输入: 若干组数据 每组数据 n m 顶点数,边数 接下去m行,边 输出:黑色最少着色数,如果不能黑白间隔那么就输出Impossible 分析: 题目有若干个联通块,最后答案就是每个联通块最少着色数目之和, 直接dfs对每个点交替着色,如果遇到已经着色的并且颜色一样,那么一定不能完成着色 通过对两种着色的情况进行计数,最后得到最小着色数目,(而重新设置初始条件再跑一遍dfs比较两次的值) 方法:dfs每个端点,每到一个端点没着色就着色,直到无法着色,如果遇到边两端颜色一样,就Impossible #include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream>

Codeforces Round #595 (Div. 3) 题解

别说谁变了你拦得住时间么 提交于 2020-01-26 00:31:46
A. Yet Another Dividing into Teams 传送门 签到,有相邻的数字 ans=2,否则 ans=1 int main(){ scanf("%d",&T); while(T--){ scanf("%d",&n); memset(vis,0,sizeof(vis)); for(int i=1,x;i<=n;i++) scanf("%d",&x),vis[x]=1; int flag=0; for(int i=1;i<=100;i++) if(vis[i]&&(vis[i-1]||vis[i+1])) {flag=1;break;} if(flag==0) printf("1\n"); else printf("2\n"); } return 0; } B. Books Exchange 传送门 找每个顶点处在的环的大小,dfs 行了 #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <queue> #include <utility> #define MAXN 200010 using namespace std; const int inf=0x3f3f3f3f; int ans=inf; int T,n,to[MAXN],len