usaco /the first wave

bzoj1572:贪心。先按时间顺序排序,然后用优先队列,如果时间不矛盾直接插入,否则判断队列中w最小的元素是否替换掉。(没用llWA了一次

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
#define REP(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ll long long
#define clr(x,c) memset(x,c,sizeof(x))
int read(){
	int x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-‘0‘,c=getchar();
	return x;
}
const int nmax=100005;
struct Node{
	int num,w;
	bool operator<(const Node&rhs)const{
	  return num<rhs.num;}
};
Node Nodes[nmax];
struct node{
	int num,w;
	bool operator<(const node&rhs)const{
	  return w>rhs.w;}
};
node nodes[nmax];
priority_queue<node>q;
int main(){
	int n=read();
	REP(i,1,n) Nodes[i].num=read(),Nodes[i].w=read();
	sort(Nodes+1,Nodes+n+1);
	REP(i,1,n) nodes[i].num=Nodes[i].num,nodes[i].w=Nodes[i].w;
	REP(i,1,n){
		node o=nodes[i];
		if(o.num>q.size()) {
			q.push(o);continue;
		}
		node tp=q.top();
		if(tp.w<o.w) q.pop(),q.push(o);
	}
	ll ans=0;
	while(!q.empty()) ans+=q.top().w,q.pop();
	printf("%lld\n",ans);
	return 0;
}

bzoj1574:贪心,将不能到达的点与相连的点集删除,然后dfs。(两个数组名相同RE了一次

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define REP(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define clr(x,c) memset(x,c,sizeof(x))
#define qwq(x) for(edge *o=head[x];o;o=o->next)
#define op() clr(head,0);pt=edges;
int read(){
	int x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-‘0‘,c=getchar();
	return x;
}
const int nmax=30005;
const int maxn=200005;
struct edge{
	int to;edge *next;
};
edge edges[maxn],*pt,*head[nmax];
bool vis[nmax],V[nmax];
void adde(int u,int v){
	pt->to=v;pt->next=head[u];head[u]=pt++;
	pt->to=u;pt->next=head[v];head[v]=pt++;
}
void dfs(int x){
	V[x]=true;
	qwq(x) if(vis[o->to]&&!V[o->to]) dfs(o->to);
}
int main(){
	op();clr(vis,true);clr(V,false);
	int N=read(),M=read(),P=read(),u,v;
	REP(i,1,M) u=read(),v=read(),adde(u,v);
	REP(i,1,P) {
		u=read();vis[u]=false;
		qwq(u) vis[o->to]=false;
    }
	dfs(1);
	int ans=N;
	REP(i,1,N) if(V[i]) ans--;
	printf("%d\n",ans);
	return 0;
}

bzoj1576:由于最短路唯一。所以有最短路径树。未在树中的边u,v对于lca(u,v)以下的点,有dist[x]=dist[u]+dist[v]+val[u,v]-dist[x](与dist[x]无关。可以将dist[u]+dist[v]+val[u,v]排序,依次更新。由于先更新的必定更优,于是可以用并查集压缩路径。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define REP(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define clr(x,c) memset(x,c,sizeof(x))
#define qwq(x) for(edge *o=head[x];o;o=o->next)
int read(){
	int x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-‘0‘,c=getchar();
	return x;
}
const int nmax=100005;
const int maxn=400005;
const int inf=0x7f7f7f7f;

struct edge{
	int to,dist;edge *next;
};
edge edges[maxn],*pt,*head[nmax];
int d[nmax],dep[nmax],fa[nmax],ans[nmax];
void adde(int u,int v,int d){
	pt->to=v;pt->dist=d;pt->next=head[u];head[u]=pt++;
	pt->to=u;pt->dist=d;pt->next=head[v];head[v]=pt++;
}

struct node{
	int x,d;
	node(int x,int d):x(x),d(d){}
	bool operator<(const node&rhs) const{
	  return d>rhs.d;}
};
priority_queue<node>q;
void dijkstra(){
	clr(d,0x7f);d[1]=0;dep[1]=0;
	q.push(node(1,0));
	while(!q.empty()){
		node tmp=q.top();q.pop();
		if(d[tmp.x]!=tmp.d) continue;
		qwq(tmp.x) if(d[o->to]>d[tmp.x]+o->dist){
			d[o->to]=d[tmp.x]+o->dist;
			dep[o->to]=dep[tmp.x]+1;fa[o->to]=tmp.x;
			q.push(node(o->to,d[o->to]));
		}
	}
}

struct zc{
	int from,to,dist;
	bool operator<(const zc&rhs) const{
	  return dist<rhs.dist;}
};
zc zcs[maxn];

void getdep(int x){

}
int update(int u,int v,int val){
	if(u==v) return u;
	if(dep[u]<dep[v]) swap(u,v);
	if(ans[u]==-1) ans[u]=val-d[u];
	return fa[u]=update(fa[u],v,val);
}

int main(){
	clr(head,0);pt=edges;
	int N=read(),M=read(),u,v,dd;
	REP(i,1,M) {
		u=read(),v=read(),dd=read(),adde(u,v,dd);
		zc &oo=zcs[i];oo.from=u,oo.to=v,oo.dist=dd;
	}
	dijkstra();
	REP(i,1,N) printf("%d:%d\n",i,dep[i]);

	int cnt=0;
	REP(i,1,M) {
		zc &oo=zcs[i];
		if(d[oo.from]==d[oo.to]+oo.dist||d[oo.to]==d[oo.from]+oo.dist) continue;
		zc &ee=zcs[++cnt];
		ee.from=oo.from,ee.to=oo.to,ee.dist=d[oo.from]+d[oo.to]+oo.dist;
	}
	sort(zcs+1,zcs+cnt+1);

	clr(ans,-1);
	REP(i,1,cnt) update(zcs[i].from,zcs[i].to,zcs[i].dist);
	REP(i,2,N) printf("%d\n",ans[i]);
	return 0;
}

bzoj1585:建图后最小割就可以了。(由于没有处理第一个点的情况WA了一次

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define REP(i,s,t)  for(int i=s;i<=t;i++)
#define clr(x,c) memset(x,c,sizeof(x))
int read(){
	int x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-‘0‘,c=getchar();
	return x;
}
const int nmax=10005;
const int maxn=200005;
const int inf=0x7f7f7f7f;
struct edge{
	int to,cap;edge *next,*rev;
};
edge edges[maxn],*pt,*head[nmax],*cur[nmax],*p[nmax];
void add(int u,int v,int d){
	pt->to=v;pt->cap=d;pt->next=head[u];head[u]=pt++;
}
void adde(int u,int v,int d){
	add(u,v,d);add(v,u,0);head[u]->rev=head[v];head[v]->rev=head[u];
}

int cnt[nmax],h[nmax];
int maxflow(int s,int t,int n){
	clr(cnt,0);cnt[0]=n;clr(h,0);
	int flow=0,a=inf,x=s;edge *e;
	while(h[s]<n){
		for(e=cur[x];e;e=e->next)  if(e->cap>0&&h[x]==h[e->to]+1) break;
		if(e){
			a=min(a,e->cap);cur[x]=p[e->to]=e;x=e->to;
			if(x==t){
				while(x!=s) p[x]->cap-=a,p[x]->rev->cap+=a,x=p[x]->rev->to;
				flow+=a,a=inf;
			}
		}else{
			if(!--cnt[h[x]]) break;
			h[x]=n;
			for(e=head[x];e;e=e->next) if(e->cap>0&&h[x]>h[e->to]+1) h[x]=h[e->to]+1,cur[x]=e;
			cnt[h[x]]++;
			if(x!=s) x=p[x]->rev->to;
		}
	}
	return flow;
}

bool vis[nmax];
int main(){
	clr(head,0);pt=edges;clr(vis,false);
	int N=read(),M=read(),P=read(),s=0,t=N+N+1;
	adde(s,1,inf);
	REP(i,1,M){
		int u=read(),v=read();
		adde(u+u,v+v-1,inf);adde(v+v,u+u-1,inf);
	}
	REP(i,1,P){
		int u=read();vis[u]=true;
	}
	adde(1,2,inf);
	REP(i,2,N){
		if(vis[i]) adde(i+i-1,i+i,inf),adde(i+i,t,inf);
		else adde(i+i-1,i+i,1);
	}
	printf("%d\n",maxflow(s,t,t+1));
	return 0;
}

bzoj1589:tarjan缩点后乱搞即可。(读入优化x=x*1+c-‘0‘,由于自己出的都是小数据所以没有发现WA了一次。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
#define REP(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define clr(x,c) memset(x,c,sizeof(x))
#define qwq(x) for(edge *o=head[x];o;o=o->next)
int read(){
	int x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-‘0‘,c=getchar();
	return x;
}
const int nmax=200005;
const int maxn=400005;
const int inf=0x7f7f7f7f;
struct edge{
	int to;edge *next;
};
edge edges[maxn],*pt,*head[nmax];
void add(int u,int v){
	pt->to=v;pt->next=head[u];head[u]=pt++;
}

int sccno[nmax],scc[nmax],pre[nmax],scc_cnt,dfs_clock=0;
stack<int>s;
int dfs(int x){
	int lowu=pre[x]=++dfs_clock;
	s.push(x);
	qwq(x){
		int to=o->to;
		if(!pre[to]) lowu=min(lowu,dfs(to));
		else if(!sccno[to]) lowu=min(lowu,pre[to]);
	}
	if(lowu==pre[x]){
		scc_cnt++;scc[scc_cnt]=0;
		while(1){
			int tmp=s.top();s.pop();
			sccno[tmp]=scc_cnt;scc[scc_cnt]++;
			if(tmp==x) break;
		}
	}
	return lowu;
}

int sum[nmax];
int getsum(int x){
	if(sum[x]) return sum[x];
	int ans=scc[x];
	qwq(x) ans+=getsum(o->to);
	return ans;
}

int main(){
	clr(head,0);pt=edges;
	int N=read(),u;
	REP(i,1,N) u=read(),add(i,u);

	scc_cnt=N;
	REP(i,1,N) if(!pre[i]) dfs(i);
	REP(i,1,N) qwq(i) if(sccno[i]!=sccno[o->to]) add(sccno[i],sccno[o->to]);
	REP(i,N+1,scc_cnt) sum[i]=getsum(i);
	REP(i,1,N) printf("%d\n",sum[sccno[i]]);
	return 0;
}

summary:

1.各种神奇的错误方式。。。

2.自己出的数据也不要太小。。。但也不要自己被自己出的数据绕晕了。。。

时间: 2024-10-10 00:27:01

usaco /the first wave的相关文章

BZOJ 3408 Usaco Heat Wave

裸的最短路题目.写一手Dijstra算法很舒服 #include <iostream> #include <queue> #include <cstring> #include <vector> #include <algorithm> #include <cstdio> #define Heap pair<int,int> using namespace std; priority_queue< Heap,vect

3408: [Usaco2009 Oct]Heat Wave 热浪

3408: [Usaco2009 Oct]Heat Wave 热浪 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 67  Solved: 55[Submit][Status][Discuss] Description Input 第1行:4个由空格隔开的整数T,C,Ts,Te. 第2到第C+1行:第i+l行描述第i条道路.有3个由空格隔开的整数Rs,Re,Ci. Output 一个单独的整数表示Ts到Te的最小费用.数据保证至少存在一条道路. Sa

COGS 696. [IOI1996][USACO 2.3] 最长前缀

★   输入文件:prefix.in   输出文件:prefix.out   简单对比时间限制:1 s   内存限制:128 MB 描述 USACO 2.3.1 IOI96 在生物学中,一些生物的结构是用包含其要素的大写字母序列来表示的.生物学家对于把长的序列分解成较短的序列(即元素)很感兴趣. 如果一个集合 P 中的元素可以通过串联(元素可以重复使用,相当于 Pascal 中的 “+” 运算符)组成一个序列 S ,那么我们认为序列 S 可以分解为 P 中的元素.元素不一定要全部出现(如下例中B

uva 1478 - Delta Wave(递推+大数+卡特兰数+组合数学)

题目链接:uva 1478 - Delta Wave 题目大意:对于每个位置来说,可以向上,水平,向下,坐标不能位负,每次上下移动最多为1, 给定n问说有多少种不同的图.结果对10100取模. 解题思路:因为最后都要落回y=0的位置,所以上升的次数和下降的次数是相同的,并且上升下降的关系满足出栈入栈的关系.即卡特兰数. 所以每次枚举i,表示有i个上升,i个下降,用组合数学枚举出位置,然后累加求和. C(2?in)?f(i)=C(2?i?2n)?f(i?1)?(n?2?i+1)?(n?2?i+2)

USACO prefix TrieTree + DP

/* ID:kevin_s1 PROG:prefix LANG:C++ */ #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <vector> #include <map> #include <set> #include <algorithm> #include <cstdlib>

【USACO 1.3.4】牛式

[題目描述 ] 下面是一个乘法竖式,如果用我们给定的那n个数字来取代*,可以使式子成立的话,我们就叫这个式子牛式. * * * x * * ---------- * * * * * * ---------- * * * * 数字只能取代*,当然第一位不能为0,况且给定的数字里不包括0. 注意一下在美国的学校中教的"部分乘积",第一部分乘积是第二个数的个位和第一个数的积,第二部分乘积是第二个数的十位和第一个数的乘积. 写一个程序找出所有的牛式. [格式] INPUT FORMAT: (f

USACO Chapter 1 Section 1.1

USACO的题解和翻译已经很多了... 我只是把自己刷的代码保存一下. 1.PROB Your Ride Is Here 1 /* 2 ID:xiekeyi1 3 PROG:ride 4 LANG:C++ 5 */ 6 7 #include<bits/stdc++.h> 8 using namespace std ; 9 10 int main() 11 { 12 freopen("ride.in","r",stdin); 13 freopen(&quo

USACO Your Ride Is Here

[USACO]Your Ride Is Here It is a well-known fact that behind every good comet is a UFO. These UFOs often come to collect loyal supporters from here on Earth. Unfortunately, they only have room to pick up one group of followers on each trip. They do,

usaco月赛,2017.1总结

T1:跳舞的奶牛 大致题意:一个体积为k的舞台能够同时容纳k只奶牛一起跳舞,他们每头奶牛的跳舞时间不同,如果有一只奶牛跳完了第k+1头奶牛就会立刻上场跳舞,当所有奶牛跳完舞以后我们认为这次表演结束.现在给出奶牛个数,最多用时,每头奶牛的跳舞时间.求舞台最小为多大. 思路:本来写了个程序以为这道题很简单,刚开始排一下序然后就行了,结果交了以后发现只过了五组,然后才发现这道题不能改变顺序(所以说为什么我改变顺序了还是能过五组,usaco的数据也好水......),所以说我想到了堆,然后就用堆写了一下