vis

Interesting Housing Problem 【HDU - 2426】【KM算法】

雨燕双飞 提交于 2019-12-19 04:52:48
HDU - 2426 经过这一道题,对KM有了更多的理解,首先,KM是一个完美匹配,也就是说,对于一个二分图的两边,X边和Y边,我们应当保证X边的点数与Y边的点数的数量是相等的,当然,我们以“少补”的策略来解决这个问题的。 然后,就是这道题了。 每一个人都不想去住自己不喜欢的房子,没有一个人会住自己不喜欢的房子,所以一旦有人要住自己不喜欢的房子,或者房子的数量不够的话,就是输出“-1”了。其次的话,输出最大权。 #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 e 2.718281828459045 #define INF 0x3f3f3f3f #define HalF (l + r)

POJ 1724 分层图最短路

こ雲淡風輕ζ 提交于 2019-12-19 00:14:45
分层图的两种建法 1:直接建k-1层图 2:给dis或vis或你需要记录信息的数组额外增加一维模拟n层图的效果 至于分层图的理解,个人认为就是有一些干扰信息时,比如免费经过一些路径或者有特殊限制的时候,可以从当前图免费跳到下一层或上一层图来转换状态。 #include <cstdio> #include<algorithm> #include<cstring> #include<queue> #include<cmath> using namespace std; const int maxn = 1e3+10, maxm = 1e5+10; int k,n,m; int tot,head[maxn],dis[101][10001],vis[101][10001]; struct Edge { int to,nxt,len,cos; }e[maxm]; struct Node{ int to,k,len; bool operator <(const Node&b)const { return len > b.len; } Node(int to,int k,int len):to(to),k(k),len(len){} }; void add(int from,int to,int l,int c) { e[tot].to = to, e[tot].len = l; e[tot]

HDU 5242 Game(贪心)

两盒软妹~` 提交于 2019-12-18 00:31:17
http://acm.hdu.edu.cn/showproblem.php?pid=5242 题意: 给出一棵树,每个节点都有一个权值,每次可以获得从根结点(1)到叶子节点上的所有权值和,每个节点只能获得一次。求k次操作后可以获得的最大权值和。 思路: 反向建图,首先求出所有节点到根节点的权值和,然后降序排序,从可以获得最大权值和的叶子节点开始计算。已经遍历过的节点就直接返回0。计算完后再次重新排序,取前面的k个较大值。 1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 const int maxn = 1e5+5; 7 typedef long long ll; 8 int tot, n, k; 9 ll val[maxn],head[maxn]; 10 bool vis[maxn]; 11 12 struct node 13 { 14 int v,next; 15 }e[maxn]; 16 17 struct Node 18 { 19 int id; 20 ll sum; 21 bool operator< (const Node& rhs)const 22 { 23 return sum>rhs.sum; 24 }

[学习笔记]网络流24题

落花浮王杯 提交于 2019-12-17 19:11:03
不按24题的顺序,按我做题的顺序 1、飞行员配对方案问题 建个图,跑遍匈牙利,让飞行员给其对应的飞机连一条边 #include <bits/stdc++.h> using namespace std; const int maxn=10000+10; int n,m,e,head[maxn],to[maxn<<1],nxt[maxn<<1],vis[maxn],tot,ans,match[maxn]; inline void add(int x,int y){ to[++tot]=y; nxt[tot]=head[x]; head[x]=tot; } int dfs(int x){ for(int i=head[x];i;i=nxt[i]){ int y=to[i]; if(!vis[y]){ vis[y]=1; if(!match[y]||dfs(match[y])){ match[y]=x;return 1; } } } return 0; } int main() { scanf("%d%d",&n,&m); int x,y;scanf("%d%d",&x,&y); while(x!=-1&&y!=-1){ if(x<=n&&y<=n+m) add(x,y); scanf("%d%d",&x,&y); } for(int i=1;i<=n;i++){ memset(vis,0

向量

人盡茶涼 提交于 2019-12-16 09:37:55
题目描述 给定一棵 $n$ 个节点的树,点的标号为 $1 \dots n$ ,边有边权。 记 $d(u, v)$ 为 $u$ 到 $v$ 的路径上边的权值和,对于每个节点 $u$ ,你需要给出一个 $m$ 维向量 $p_u = \{p_{u,1}, \dots, p_{u,m}\}$ ,使得对于任意点对 $u,v$ ,满足 $d(u, v) = max\{|p_{u,i} − p_{v,i}|\}$ 。 数据范围 $2 \le n \le 1000$ ; $1 \le w_i \le 10^5$ ; $m \le 16$ 题解 怎么想到点分的不知道。 考虑一个点分中心 $root$ ,把子树尽量按 $size$ 均分成两部分,然后使用一维向量,将 $A$ 集合的值设为 $deep$ , $B$ 集合设为 $-deep$ , $root$ 设为 $0$ ,然后将 $root$ 分别加入两边集合继续递归下去得到两个不同的向量,然后将其中一个向量平移成另一个向量即可,要把向量上所属集合也要平移。 代码 #include <bits/stdc++.h> using namespace std; const int N=1005,M=N<<1; int n,hd[N],V[M],nx[M],W[M],t,S[N],sz[N],rt; int o,vis[N],b[N],son[N],f[N]

nitacm 2019校赛E雷顿女士与平衡树(并查集维护)

僤鯓⒐⒋嵵緔 提交于 2019-12-16 00:00:08
题目链接: https://ac.nowcoder.com/acm/contest/2995/E 题意: 树上从u到v简单路径上所有点权中,最大值与最小值的差值为balance(u,v)。 T组(T<=10),n(1<=n<=5e5),n个a[i](1<=a[i]<=1e9)表示点权,n-1个u和v,表示u、v两点有边连接,保证构成一棵树 求树的balance%1e9 样例: 答案为179 题解: 最大值与最小值分别计算。 求最大值的方法:从小到大将每个点与相连的点用并查集合并,同时维护每个联通块的size,此时显然可以计算此点作为最大值的路径条数。 计算最小值的方法同理。 思路: 计算最大值先按点权排序 点: 4,5,6,8,9,3,10,7,1,2 点权:2,4,5,5,5,6, 6,8,9,9 先把点④的vis设为1,表示已访问,然后遍历所有与点④相连的已经访问的点,未找到。 再把点⑤的vis设为1,表示已经访问,然后遍历所有与点⑤相连的已经访问的点,找到点④,此时需要做如下处理: 与点④连通的联通块(共有size1个点)的最大点权都为2,与点⑤连通的联通块(共有size2个点)的最大点权都为4, 从左边联通块任取一点,右边联通块里任取一点,两点之间的最大点权都为4,共有size1*size2对点,再乘上⑤的点权4,即为这一部分的max值 然后联合两个块,重新计算size

DFS和BFS

二次信任 提交于 2019-12-14 09:11:32
1.油田连通块 链接地址: 地址 递归DFS # include <cstdio> # include <iostream> # include <algorithm> # include <cstring> using namespace std ; char map [ 110 ] [ 110 ] ; bool vis [ 110 ] [ 110 ] = { 0 } ; //布尔类型减少内存浪费 int orient [ 8 ] [ 2 ] = { 1 , 1 , 1 , 0 , 1 , - 1 , 0 , 1 , 0 , - 1 , - 1 , 1 , - 1 , 0 , - 1 , - 1 } ; //八个方向的遍历 int m , n ; void DFS ( int x , int y ) { if ( x < 0 || x >= m || y < 0 || y >= n ) return ; if ( vis [ x ] [ y ] == 1 || map [ x ] [ y ] != '@' ) return ; vis [ x ] [ y ] = 1 ; for ( int i = 0 ; i < 8 ; i ++ ) { DFS ( x + orient [ i ] [ 0 ] , y + orient [ i ] [ 1 ] ) ; } } int main

[题解]UOJ#41 矩阵变换

狂风中的少年 提交于 2019-12-14 03:01:52
传送门 分析 先随便选 记 \(p[i][j]\) 表示 \(j\) 这个数在第 \(i\) 行的位置,考虑不合法的情况: 假设第i行选择的数为 \(x\) ,第 \(j\) 行选择的为 \(y\) ,且 \(p[i][x]<p[j][x]<p[j][y]\) ,那么在第 \(p[j][x]\) 列就会有两个 \(x\) 出现,不满足条件。 那么,我们最终的目标就是使得上述情况不存在 可以转化成稳定婚姻问题: 对于每一行,优先去选在左边的 对于每一个数,优先匹配 \(p[i][x]\) 大的 \(i\) 代码 #include<bits/stdc++.h> #define rep(X,A,B) for(int X=A;X<=B;X++) #define tep(X,A,B) for(int X=A;X>=B;X--) #define LL long long const int N=210; using namespace std; int n,m,chk; int ans[N],vis[N],p[N][N],a[N][N]; queue<int>Q; void READ(){ scanf("%d%d",&n,&m); int x=0; rep(i,1,n){ rep(j,1,m){ scanf("%d",&x); if(x)p[i][x]=j; a[i][j]=x; } } }

leetcode回溯算法--基础难度

可紊 提交于 2019-12-10 22:58:15
都是直接dfs,算是巩固一下 电话号码的字母组合 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 思路 一直搜索,到终点判断是否已经出现,未出现则加入集合 代码 class Solution { set<string>s; map<char,string>m; public: void dfs(string d, string cur, int step){ if(step>d.size()){ return; } if(step==d.size()){ if(s.count(cur)>0){ return; }else{ s.insert(cur); } } string tmp=m[d[step]]; for(int i=0;i<tmp.size();++i){ dfs(d,cur+tmp[i],step+1); } } vector<string> letterCombinations(string digits) { m.insert(make_pair('2',"abc")); m.insert(make_pair('3',"def")); m.insert(make_pair('4',"ghi")); m.insert(make_pair('5',"jkl")); m

洛谷 P1832 A+B Problem(再升级)

人盡茶涼 提交于 2019-12-10 22:08:21
题目传送门 解题思路: 先搞一遍欧拉筛,然后f[i]表示i的答案,对于1~n的所有素数,都大于其的数的f改一下. AC代码: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 5 using namespace std; 6 7 long long n,p[1001],vis[1001],tot,f[1001]; 8 9 inline void oulashai() { 10 memset(vis,1,sizeof(vis)); 11 vis[0] = vis[1] = 0; 12 for(int i = 2;i <= n; i++) { 13 if(vis[i]) p[++tot] = i; 14 for(int j = 1;j <= tot; j++) { 15 if(i * p[j] > n) break; 16 vis[i*p[j]] = 0; 17 if(i % p[j] == 0) break; 18 } 19 } 20 } 21 22 int main() { 23 scanf("%lld",&n); 24 oulashai(); 25 f[0] = 1; 26 for(int i = 1;i <= tot; i++) 27 for(int j = p[i];j <= n; j++) 28 f