vis

图的基本遍历算法的实现(BFS & DFS)复习

萝らか妹 提交于 2019-12-24 03:33:50
#include <stdio.h> #define INF 32767 typedef struct MGraph{ char vertexs[10]; int edge[10][10]; int ver_num, edge_num; }MGraph; void create_graph(MGraph *graph) { int i, j; getchar(); for(i = 0; i < graph->ver_num; ++i) scanf("%c%*c",&(graph->vertexs[i])); for(i = 0; i < graph->ver_num; ++i) { for(j = 0; j < graph->ver_num; ++j) { if(i == j) graph->edge[i][i] = 0; else graph->edge[i][j] = INF; } } int vi, vj, val; for(i = 0; i < graph->edge_num; ++i) { scanf("%d %d %d", &vi, &vj, &val); graph->edge[vi][vj] = graph->edge[vj][vi] = val; } } void print_graph(MGraph graph) { int i,j; for(i = 0; i

带花树算法学习笔记

笑着哭i 提交于 2019-12-24 02:47:49
带花树算法学习笔记 难得yyb写了一个这么正式的标题 Q:为啥要学带花树这种东西啊? A:因为我太菜了,要多学点东西才能不被吊打 Q:为啥要学带花树这种东西啊? A:因为我做自己的专题做不动了,只能先去“预习”ppl的专题了 Q:为啥要学带花树这种东西啊? A:因为可以用来做题啊,比如某WC题目 先推荐一个很皮很皮的带花树讲解: 戳这里嗷 QaQ 言归正传 带花树的算法用来解决一般图的最大匹配问题 说起来,是不是想起来网络流里面的最小路径覆盖? 或者二分图的最大匹配的问题? 的确,带花树解决一般图的最大匹配问题类似于这些东西。 但是肯定是有不同的。 比方说: 我们用匈牙利的思路来解决一般图 我们是可以很容易就让算法挂掉的 只需要一个奇环就可以啦 (让我偷张图片过来) 看见没有 有了一个奇环,在匹配的时候黑白就会翻转过来。 所以我们当然不能直接用匈牙利来做。 但是,这样的问题当然需要解决, 所以就有了带花树算法。 你可以理解为: 带花树算法=匈牙利算法+处理奇环 因为不打算长篇大论, 我按照带花树的步骤来写写这个算法。 (随时对比匈牙利算法) 匈牙利算法第一步:找到一个未被匹配的点,从这个点开始匹配 带花树算法第一步:找到一个未被匹配的点,从这个点开始匹配 貌似没有区别。。。 接下来匈牙利算法会用 \(dfs\) 来寻找增广路 带花树算法使用 \(bfs\) 将当前点丢进队列里面

二分图最大匹配

a 夏天 提交于 2019-12-24 01:13:51
HDU 1150: http://acm.hdu.edu.cn/showproblem.php?pid=1150   最小覆盖点 == 最大匹配数( 选取最少的点数,使这些点和所有的边都有关联——把所有的边的覆盖 ) 两台机器,有n和m个工作模式,起始工作模式都为0,现在有k件工作,第i件工作可分别在两个机器上用各自的模式工作,但换模式要重启,问重启的最小次数。 写的时候因为是找二分最大匹配的题目时找到写的,想到了二分上去,也知道是求最小覆盖点 == 最大匹配数,但不是很能理解,先把代码写了再说。 写的时候注意起始模式是0,所以换模式时把0的排除再外。(因为这个原因错了很多次) 一:邻接阵做法 代码 #include<iostream>using namespace std;int n,m,k;int map[105][105]; //记录X,Y对应点可否连接int vis[105]; //每次找增广路时对Y中点是否访问int dir[105]; //Y中点匹配的X中点的位置int find(int a){ int i; for(i=0;i<m;i++) { if(map[a][i]==1 && vis[i] == 0) { vis[i] = 1; if(dir[i] == -1 || find(dir[i])) { dir[i] = a; return 1; } } }

UVa 1599 (字典序最小的最短路) Ideal Path

主宰稳场 提交于 2019-12-23 12:52:14
题意: 给出一个图(图中可能含平行边,可能含环),每条边有一个颜色标号。在从节点1到节点n的最短路的前提下,找到一条字典序最小的路径。 分析: 首先从节点n到节点1倒着BFS一次,算出每个节点到节点n个最短距离d i 然后从节点1开始再一次BFS,在寻找下一个节点时,必须满足下一个节点v满足对于当前节点u,有d u = d v + 1,这样才能保证在最短路上。 在这个条件下还要满足v的颜色编号是最小的。因为可能有多个颜色相同的最小编号,所以这些节点都要保留下来。 图的表示方式:这里如果再用往常的邻接表发现不适用了,所以G[u]中保存的与u邻接的edges中边的编号。 1 #include <cstdio> 2 #include <vector> 3 #include <cstring> 4 #include <queue> 5 #include <algorithm> 6 using namespace std; 7 8 const int maxn = 100000 + 10; 9 const int INF = 1000000000 + 10; 10 11 struct Edge 12 { 13 int u, v, c; 14 Edge(int u=0, int v=0, int c=0):u(u), v(v), c(c) {} 15 }; 16 17 vector<Edge>

Hdu1547泡泡龙

旧城冷巷雨未停 提交于 2019-12-23 03:00:42
Bubble Shooter Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1069 Accepted Submission(s): 463 Problem Description Bubble shooter is a popular game. You can find a lot of versions from the Internet. The goal of this game is to clean the bubbles off the field. Every time you just point the cannon to where you want the next bubble to go, and if three or more of bubbles with the same color came together (including the newly shot bubble), they will detonate. After the first explode, if some bubbles are disconnected from the bubble(s) in the

线性筛总结

雨燕双飞 提交于 2019-12-22 21:54:46
线性筛 总体思想:筛某个合数时,总是这个数的最小质因数筛除它。 划重点 :因数个数 d ( n ) d(n) d ( n ) 、因数和 s ( n ) s(n) s ( n ) 、欧拉函数 p h i ( n ) phi(n) p h i ( n ) 、莫比乌斯函数 m u ( n ) mu(n) m u ( n ) 等均为 n n n 的积性函数,能很好的利用“最小质因数”筛法性质。 一、筛质数 处理出 1 e 8 1e8 1 e 8 以内的素数用时 1 s 1s 1 s 左右,实测复杂度为 O ( n ) O(n) O ( n ) 带一个小常数。 1 e 7 1e7 1 e 7 以内则 0.1 s 0.1s 0 . 1 s 左右。 const int maxn = 1e7 + 7 ; const int maxp = 7e5 + 7 ; bool vis [ maxn ] ; int prime [ maxp ] , tot ; void getPrime ( ) { for ( int i = 2 ; i < maxn ; ++ i ) { if ( ! vis [ i ] ) prime [ ++ tot ] = i ; for ( int j = 1 ; j <= tot && i * prime [ j ] < maxn ; ++ j ) { vis [ i *

洛谷P3381 【模板】最小费用最大流

Deadly 提交于 2019-12-22 17:19:29
P3381 【模板】最小费用最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用。 输入输出格式 输入格式: 第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。 接下来M行每行包含四个正整数ui、vi、wi、fi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi),单位流量的费用为fi。 输出格式: 一行,包含两个整数,依次为最大流量和在最大流量情况下的最小费用。 输入输出样例 输入样例#1: 复制 4 5 4 3 4 2 30 2 4 3 20 3 2 3 20 1 2 1 30 9 1 3 40 5 输出样例#1: 复制 50 280 说明 时空限制:1000ms,128M (BYX:最后两个点改成了1200ms) 数据规模: 对于30%的数据:N<=10,M<=10 对于70%的数据:N<=1000,M<=1000 对于100%的数据:N<=5000,M<=50000 样例说明: 如图,最优方案如下: 第一条流为4-->3,流量为20,费用为3*20=60。 第二条流为4-->2-->3,流量为20,费用为(2+1)*20=60。 第三条流为4-->2-->1-->3,流量为10,费用为(2+9+5)*10=160。 故最大流量为50

素数圆环(dfs)

蹲街弑〆低调 提交于 2019-12-21 15:40:35
题目描述 如图所示为一个由n个圆圈构成的圆环。将自然数1,2,…,n放入圆圈内,并且要求任意两个相邻的圆圈内的数字之和为素数。请问给你圆圈数,你能给出放置自然数的所有正确方案吗? 注意:圆圈中的数字一定是从1开始的,并且连续不重复。 输入描述: 输入包含多组测试数据。每组输入占一行,为整数n(0<n<20),表示圆圈数。 输出描述: 对于每组输入,输出所有正确的方案,按字典序从小到大排序。每组输出后输出一个空行。具体输出格式见输出样例。 输入 6 8 输出 Case 1: 1 4 3 2 5 6 1 6 5 2 3 4 Case 2: 1 2 3 8 5 6 7 4 1 2 5 8 3 4 7 6 1 4 7 6 5 8 3 2 1 6 7 4 3 8 5 2 # include <bits/stdc++.h> using namespace std ; bool is [ 1000 ] , vis [ 25 ] ; int n , cas = 0 ; int a [ 25 ] ; int pos ; void sol ( ) { is [ 0 ] = is [ 1 ] = true ; for ( int i = 2 ; i < 1000 ; i ++ ) { if ( is [ i ] == true ) continue ; for ( int j = 2 ; i * j <

江西理工摸底测试

谁说胖子不能爱 提交于 2019-12-20 06:39:31
A题:water: 一开始写的时候,写超时了:一是有的条件没加上去,二是没有进行优化。 后来用了set将没有装满的瓶子的下标放进去,并进行排序,然后二分查找找后面比他大的下标。 我觉得这样的思路非常的ok,应该没毛病,但是就是老wa,原来在后面的循环没有赋初值。 下面是AC代码 1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <set> 5 6 using namespace std; 7 const int ma = 1e5 + 10; 8 int t,n,m; 9 set<int> s; 10 struct node 11 { 12 int x,y; 13 }num[ma]; 14 15 int main() 16 { 17 scanf("%d",&t); 18 while(t--) 19 { 20 s.clear(); 21 scanf("%d%d",&n,&m); 22 for(int i = 1;i <= n;i++) 23 scanf("%d",&num[i].x),s.insert(i),num[i].y=0; 24 int a,b,c; 25 while(m--) 26 { 27 scanf("%d%d",&a,&b); 28 c = min(num[a].x -

PAT(甲级)2019年秋季考试

 ̄綄美尐妖づ 提交于 2019-12-19 08:26:55
第一题用搜索,超时了,待补 更新第一题思路 dfs + 剪枝,首先确定 n的最后一位数字肯定是9,为什么呢,因为 任意两个相邻的数肯定互为质数(gcd=1),所以 n 的末尾肯定是9,这样n+1产生的各个位数和相加的和 才能有可能和sum(n)产生gcd>2的素数, 所以k可以剪枝成k-1,缩小一位,复杂度降低很多。。。这样估计就能AC了。 另外判断n和n+1两个数的各个位数之和的gcd是否为大于2的素数,可以提前预处理(数据量<90), 第一题参考链接 7-1搜索 12/20分 原来写的代码,超时2个测试点 #include<bits/stdc++.h> using namespace std; int n,k,m; typedef long long ll; ll starts = 0; ll endss = 0; bool flag = false; bool first = true; int t = 1; int sums(ll x){ int ans = 0; while(x){ ans += x%10; x/=10; } return ans; } ll gcd(ll a,ll b){ if(b == 0) return a; return gcd(b,a%b); } bool solve(ll x){ if(x <= 2) return false; for(int