vis

LOJ10067 构造完全图

我怕爱的太早我们不能终老 提交于 2019-12-01 06:58:04
题目描述 对于完全图 ,若有且仅有一棵最小生成树为 ,则称完全图 是树 扩展出的。 给你一棵树 ,找出 能扩展出的边权和最小的完全图 。 输入格式 第一行 表示树 的点数; 接下来 行三个整数 ;描述一条边( )权值为 ; 保证输入数据构成一棵树。 输出格式 输出仅一个数,表示最小的完全图 的边权和。 样例 样例输入 4 1 2 1 1 3 1 1 4 2 样例输出 12 输入文件(tree1.in) 10 5 10 1 5 4 4 4 9 6 2 9 6 8 4 6 1 5 2 3 10 9 5 7 7 6 9 3 答案文件(tree1.out) 319 WA 10分 #include <bits/stdc++.h> using namespace std; const int N = 10000 + 5; struct T { int p, d; }; bool cmp(T x, T y) { return x.d < y.d; } int vis[N]; T t[N]; int main() { int n, ans = 0; cin >> n; for (int i = 1; i < n; i++) { int x, y, z; cin >> x >> y >> z; ans += z; t[y].p = x; t[y].d = z; } sort(t + 1, t + n

模板整理

一世执手 提交于 2019-12-01 05:47:43
前言 众所周知,一些算法和数据结构是很板子化的,如果我们要用需要先记住他( 这不废话吗 ) 2019.10.8 线段树(区间加与区间求和) 注意右子树区间大小为 \(r-(mid+1)+1=r-mid\) #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #define re register #define int long long #define maxn 100010 #define ls p<<1 #define rs p<<1|1 #define size (r-l+1) using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int ans; int n,m,sums[maxn<<2],lazy[maxn<<2],opt,x,y,k,a[maxn]; void push_up(int p) { sums[p]=sums[ls]+sums[rs];

二分图匹配总结与习题

这一生的挚爱 提交于 2019-12-01 05:27:57
模板: (用时间戳记录可以避免每一次memset vis) #include<bits/stdc++.h> using namespace std; #define N 2005 #define M 1000005 int match[N],vis[N],T=0;//只存一边的匹配点 int to[M],head[N],tot=0,nex[M]; void add(int a,int b) { to[++tot]=b; nex[tot]=head[a]; head[a]=tot; } bool dfs(int x) { if(vis[x]==T) return false; vis[x]=T; for(int i=head[x];i;i=nex[i]) if(!match[to[i]]||dfs(match[to[i]])) { match[to[i]]=x; match[x]=to[i]; return true; } } int main() { int n,m,e,ans=0,a,b; cin>>n>>m>>e; while(e--) { scanf("%d%d",&a,&b); if(a<=n&&b<=m) add(a,b+m),add(b+m,a); } for(int i=1;i<=m;i++) //一定是遍历m 因为存储时是加了m 说明有m长度的一边需要遍历 { T+

【LGOJ1606】白银莲花池

醉酒当歌 提交于 2019-12-01 05:04:55
为了让奶牛们娱乐和锻炼,农夫约翰建造了一个美丽的池塘。 这个长方形的池子被分成了M行N列个方格(1≤M,N≤30) 一些格子是坚固得令人惊讶的莲花,还有一一些格子是岩石,其余的只是美丽、纯净、湛蓝的水 贝西正在练习芭蕾舞,她站在一朵莲花上 ,想跳到另一朵莲花上去,她只能从一一朵莲花跳到另-朵莲花上 既不能跳到水里,也不能跳到岩石上,贝西的舞步很像象棋中的马步,最多时,西会有八个移动方向可供选择 约翰一直在观看贝西的芭蕾练习,发现她有时候不能跳到终点,因为中间缺了一些荷叶 于是他想要添加几朵莲花来帮助贝西完成任务 一贯节俭的约翰只想添加最少数星的莲花。当然,莲花不能放在石头上 请帮助约翰确定必须要添加的莲花的最少数量,以及有多少种放置这些莲花的方法 从起点,和水,向每一个可以放荷叶的位置建边 SPFA跑最短路的时候,顺便搞一下最短路计数 跑最短路的时候是点权,而要求的是边权 所以把答案减一即可 87分改了一个多小时,结果是dfs里面没有判vis... 代码: #include<bits/stdc++.h> #define ll long long #define N 1000005 #define inf 123456789123456789 using namespace std; int n,m,u,v,xx1,yy1,xx2,yy2; int a[35][35],id[35]

「ZJOI2006」物流运输

别等时光非礼了梦想. 提交于 2019-12-01 04:24:08
题目 【内存限制:$256MiB$】 【时间限制:$1000ms$】 【标准输入输出】 【题目类型:传统】 【评测方式:文本比较】 【题目描述】 物流公司要把一批货物从码头 A 运到码头 B。由于货物量比较大,需要 $n$ 天才能运完。货物运输过程中一般要转停好几个码头。物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪。 由于各种因素的存在,有的时候某个码头会无法装卸货物。这时候就必须修改运输线路,让货物能够按时到达目的地。但是修改路线是一件十分麻烦的事情,会带来额外的成本,因此物流公司希望能够订一个 $n$ 天的运输计划,使得总成本尽可能地小。 【输入格式】 第一行是四个整数 $n(1\le n\le 100),m(1\le m\le 20),K,e$。$n$ 表示货物运输所需天数,$m$ 表示码头总数,$K$ 表示每次修改运输路线所需成本。 接下来 $e$ 行每行是一条航线描述,包括了三个整数,依次表示航线连接的两个码头编号以及航线长度 $(>0)$。其中码头 A 编号为 $1$,码头 B 编号为 $m$。单位长度的运输费用为 1。航线是双向的。 再接下来一行是一个整数 $d$,后面的 $d$ 行每行是三个整数 $P(1<P<m),a,b(1\le a\le b\le n)$。表示编号为 $P$ 的码头从第 $a$ 天到第 $b$ 天无法装卸货物

图论模板

*爱你&永不变心* 提交于 2019-12-01 02:48:19
1 /* // 图论模板 // */ 2 //----------------------------------------------------------------------------- 3 /*卡常小技巧*/ 4 #define re register 5 #define max(x,y) ((x)>(y)?(x):(y)) 6 #define min(x,y) ((x)<(y)?(x):(y)) 7 #define swap(x,y) ((x)^=(y)^=(x)^=(y)) 8 #define abs(x) ((x)<0?-(x):(x)) 9 inline + 函数(非递归) 10 static 相当于全局变量,防止爆栈,且不用重复申请空间,初值为0 11 //----------------------------------------------------------------------------- 12 /*前向星邻接表*/ 13 //单向链表 14 int tot,first[100010]; 15 struct node{int u,v,w,next;}edge[200010]; 16 inline void add(re int x,re int y,re int w){ 17 edge[++tot].u=x; 18 edge[tot]

差分约束系统

一曲冷凌霜 提交于 2019-12-01 02:02:12
差分约束系统用于解决N元一次不等式组。 之前感觉学的模模糊糊,现在理得比较清楚后做一个总结。 1.不等式怎么转换 先是a-b ≤ c 对于最短路,有这样的不等式:dis(u) ≤ dis(v) + val(v,u) 变形得:dis(u) - dis(v) ≤ val(v,u),与a-b ≤ c很相似 那么对于形如a-b ≤ c的不等式,我们可以从点b向点a连接一条长度为c的边。 2.跑最长路还是最短路 这与建图的方式有关。 a-b ≤ c--->从点b向点a连接一条长度为c的边跑最短路。 也可以是 --->从点a向点b连接一条长度为-c的边跑最长路。 如果求的是两个变量差的最大值,那么需要将所有不等式转变成"<=",建图后求最短路。(即求所有满足条件里的最小的)。 如果求的是两个变量差的最小值,那么需要将所有不等式转化成">=",建图后求最长路。(即要求所有的最小值都满足)。 而最短路和最长路是可以通过不等式移项相互转化的。 特殊连边 我们在建图的时候,并不是只有连和不等式转化的边,还有一些特殊的“隐藏边”。 可能是某个点有一定的限制。 比如一个点的位置只能填1或0,处理成前缀和以后就会有0<=sum[i] - sum[i-1]<=1。 或者说这个点有权值,为了维护这个权值,我们建一个0点,互相连边。 更多的还要多做不同的题。 无解情况 参考 如果是求解最长路 (最 小值

【模板】欧拉回路(一笔画问题)

末鹿安然 提交于 2019-11-30 23:13:44
(摘自https://www.cnblogs.com/abc1604831024/p/9077112.html) 欧拉回路 就是给一个图, 存在一条回路把所边经过且每条边只经过一次 。 对于 无向图 :   存在欧拉回路的条件: 每个点的度都为偶数 ;   存在欧拉路的条件: 有且只有两个点的度为一,且这两个点分别为起点和终点 ; 对于 有向图 :   存在欧拉回路的条件: 每个点出度等于入度 ;   存在欧拉路的条件: 存在一个点出度比入度多一作为起点,存在一点入度比出度多一作为终点,其余点出度等于入度 ; 求欧拉回路的方法—— 基本(套圆)法    dfs搜索,不能再往下走便回溯,回溯时记录路径,回溯时不清除对边的标记,最后求出来的路径就是欧拉回路。 举例 (1)走<1,2>,<2,3>,<3,4>,<4,5>,<5,1>,然后无路可走,就回溯记录下回溯路径<1,5>,<5,4>,4点有其它路壳走。 (2)<4,8>,<8,3>,<3,6>,<6,7>,<7,2>,<2,4>,无路可走,然后回溯<1,5>,<5,4>,<4,2>,<2,7>,<7,6>,<6,3>,<3,8>,<8,4>,<4,3>,<3,2>,<2,1>。 记录下的路径<1,5>,<5,4>,<4,2>,<2,7>,<7,6>,<6,3>,<3,8>,<8,4>,<4,3>,<3,2>,<2,1

洛谷P2296 寻找道路

我们两清 提交于 2019-11-30 22:58:29
  题意:在有向图 G G 中,每条边的长度均为 1 1,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 路径上的所有点的出边所指向的点都直接或间接与终点连通。 在满足条件 1 1的情况下使路径最短。    注意:图 G G 中可能存在重边和自环,题目保证终点没有出边。    请你输出符合条件的路径的长度。     少有的题意简明的题目   解法:反向建图,bfs终点到源点的,记录每个点正的度数和反的度数,比较后再把正的图建出。最后bfs #include<iostream> #include<cstring> #include<queue> using namespace std; const int MAXN=10005,MAXM=200005; struct Edge{int next,to;}edge[MAXM]; struct EDge{int u,v;}EDGE[MAXM]; int n,m,s,t,n_e,head[MAXN],cnt[MAXN][2],dis[MAXN]; bool vis[MAXN]; void spfa(int x); void bfs(int x); void addedge(int from,int to); int main() { cin>>n>>m; for(int i=1;i<=m;i++) { int u

10/10

允我心安 提交于 2019-11-30 22:39:48
A: 题意:给一个大小为n的数组A,让你把A分成若干个(1 or more)新的数组,使得新数组的和不为0; 解:NO的情况只有 数组内所有元素都为0   YES的情况:1.数组A的所有元素和不为0:直接输出(1,n);         2.数组A的所有元素和为0:必定存在sum(1,i)!=0,sum(i+1,n)!=0;//(sum(1,i)表示元素下标和(1-i)) #include <bits/stdc++.h> using namespace std; const int MAXN=1e5+10; int a[MAXN]; int main(){ int n; cin>>n; int sum=0; for(int i=1;i<=n;i++){ cin>>a[i]; sum+=a[i]; } if(sum){ cout<<"YES"<<endl; cout<<1<<endl; cout<<1<<' '<<n<<endl; } else{ int flag=0; for(int i=1;i<=n;i++){ sum+=a[i]; if(sum){ flag=1; cout<<"YES"<<endl; cout<<2<<endl; cout<<1<<' '<<i<<endl; cout<<i+1<<' '<<n<<endl; break; } } if(!flag)cout<<