A - A
POJ - 1149
题意:m个猪圈,n个顾客,每个顾客有一些猪圈的钥匙,猪圈的猪可以相互交换,求最大卖出猪数。
考虑猪圈的猪如果交换,实际上还是在顾客之间流动,所以以猪圈为单位建模并不合适,因此对于每一个猪圈,能访达所有的顾客都连一条边,因为
猪圈的交换实际上还是在顾客之间流动,对于每一个猪圈的第一个顾客连一条边 流量 a[i] 到源点,这样就保证了流量限制,因为第一个顾客能买到猪
的数量不会超过 a[i], 然后把每一个顾客连一条到源点 b[i],表示顾客的限制,跑一遍最大流,
这样保证了流量限制,
#include <cstdio> #include <cstring> #include <queue> #include <vector> #include <algorithm> using namespace std; #define pb push_back const int inf=0x3f3f3f3f; const int N=1e3+50; int n,m,S,T; struct Dinic{ int head[N],dep[N]; int ecnt; struct edge{ int v,flow,next; }e[N<<1]; void init(){ memset(head, -1, sizeof head); ecnt = 0; } void addedge(int u, int v, int flow) { e[ecnt].v=v;e[ecnt].flow=flow;e[ecnt].next=head[u];head[u]=ecnt++; } bool BFS(){ memset(dep,0,sizeof dep); queue<int>Q; Q.push(S);dep[S]=1; while(!Q.empty()){ int u=Q.front();Q.pop(); for(int i=head[u];~i;i=e[i].next){ if(e[i].flow&&!dep[e[i].v]){ dep[e[i].v]=dep[u]+1; Q.push(e[i].v); } } } return dep[T]; } int DFS(int u, int f){ if(u==T||f==0)return f; int w,used=0; for(int i=head[u];~i;i=e[i].next){ if(e[i].flow&&dep[e[i].v]==dep[u]+1){ w=DFS(e[i].v,min(f,e[i].flow)); e[i].flow-=w;e[i^1].flow+=w; used+=w;f-=w; } } if(!used)dep[u]=-1; return used; } int maxflow() { int ans=0; while(BFS()){ ans+=DFS(S,inf); } return ans; } }dinic; int a[N],b[N]; vector<int>G[N]; int main(){ scanf("%d %d",&m,&n); for(int i=1;i<=m;i++)scanf("%d",&a[i]); for(int i=1,A,u;i<=n;i++){ scanf("%d",&A); while(A--){scanf("%d",&u);G[u].pb(i);} scanf("%d",&b[i]); } dinic.init(); S=0;T=n+1; for(int i=1;i<=m;i++){ dinic.addedge(S,G[i][0],a[i]); dinic.addedge(G[i][0],S,0); } for(int i=1;i<=m;i++){ for(int j=0;j<G[i].size()-1;j++){ dinic.addedge(G[i][j],G[i][j+1],inf); dinic.addedge(G[i][j+1],G[i][j],0); } } for(int i=1;i<=n;i++){ dinic.addedge(i,T,b[i]); dinic.addedge(T,0,0); } printf("%d\n",dinic.maxflow()); // system("pause"); return 0; }View Code
G - G
每个机器可以把相隔一个点的点感染,那么如果一个联通块感染,连到其他联通块都可以被感染。
染一个联通块:有奇环就染一个点就行了,没有奇环要染两个点。
#include<bits/stdc++.h> using namespace std; #define pb push_back const int N=5e5+50; int step[N]; vector<int>e[N]; int c; void dfs(int u,int dfn){ step[u]=dfn; for(int i=0;i<e[u].size();i++){ int v=e[u][i]; if(!step[v])dfs(v,dfn+1); else { int d=abs(step[u]-step[v]); if( (d+1)%2==1)c=0; } } } int main(){ int n,m; c=1; scanf("%d %d",&n,&m); for(int i=1;i<=n;i++)step[i]=0; int u,v; while(m--){ scanf("%d %d",&u,&v); e[u].pb(v); e[v].pb(u); } int ans=0; for(int i=1;i<=n;i++){ if(step[i]==0){ dfs(i,1); ans++; } } // cout<<ans<<endl; printf("%d\n",ans-1+c); // system("pause"); return 0; }View Code
K - K
考虑两个蚂蚁即使碰到后相反走,并不影响最终结果,扫一遍即可。
#include<cstdio> #include<algorithm> using namespace std; const int N=1e6+50; const int inf=0x3f3f3f3f; int a[N],l[N],r[N]; int main(){ int t; scanf("%d",&t); while(t--){ int len,n; scanf("%d %d",&len,&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); int Min=-1,Max=-1; int thismin,thismax; for(int i=1;i<=n;i++){ l[i]=a[i],r[i]=len-a[i]; thismin=min(l[i],r[i]); thismax=max(l[i],r[i]); Min=max(Min,thismin); Max=max(Max,thismax); } printf("%d %d\n",Min,Max); } // system("pause"); return 0; }View Code
L - L
裸
#include <cstdio> #include <cmath> // #include <bits/stdc++.h>a const int N=160; int get_ephi(int n) { int m = int(sqrt(n + 0.5)); int ans = n; for (int i = 2; i <= m; i++) { if (n % i == 0) { ans = ans / i * (i - 1); while (n % i == 0) n /= i; } } if (n > 1) ans = ans / n * (n - 1); return ans; } int main(){ int n; while(~scanf("%d",&n),n){ printf("%d\n",get_ephi(n)); } // system("pause"); return 0; }View Code