• 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
    ",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
    ",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
    ",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
    ",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
    ",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
    ",sum[sccno[i]]);
    	return 0; 	
    }
    

    summary:

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

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

  • 相关阅读:
    hihocoder #1138 : Islands Travel
    关于c中的inline
    LUOGU P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm
    LUOGU P1908 逆序对
    归并排序 (模板)
    tyvj 1864 守卫者的挑战
    loj #10001. 「一本通 1.1 例 2」种树
    bzoj 1026: [SCOI2009]windy数
    BZOJ 4521: [Cqoi2016]手机号码
    LUOGU 3089 后缀排序(模板)
  • 原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5694637.html
Copyright © 2020-2023  润新知