T1 T1的话是一个明显得不能再明显得二分图匹配,然而我少判断了一组情况80P#include<map> #include<queue> #include<cmath> #include<cctype> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define qread(x) x=read() #define mes(x,y) memset(x,y,sizeof(x)) #define mpy(x,y) memcpy(x,y,sizeof(x)) #define Maxn 1000 #define Maxm 100000 #define INF 2147483647 inline int read(){ char ch=getchar(); int f=1,x=0; 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; } using namespace std; struct node{ int x,y,next; }a[Maxm+1];int len,first[Maxn+1]; int t,n,m,k,ans,xlnum,ylnum,match[Maxn+1],v[Maxn+1]; bool xnum[Maxn+1],ynum[Maxn+1]; void ins(int x,int y){ len++; a[len].x=x;a[len].y=y; a[len].next=first[x];first[x]=len; } bool findmuniu(int x){ for(int k=first[x];k>0;k=a[k].next){ int y=a[k].y; if(v[y]!=v[0]){ v[y]=v[0]; if(match[y]==0||findmuniu(match[y])==true){ match[y]=x; return true; } } } return false; } int main(){ qread(t); while(t--){ qread(n);qread(m);qread(k); len=0;mes(first,0); xlnum=0;mes(xnum,false); ylnum=0;mes(ynum,false); for(int i=1;i<=k;i++){ int x,y; scanf("%d%d",&x,&y); if(xnum[x]==false){ xnum[x]=true; xlnum++; } if(ynum[y]==false){ ynum[y]=true; ylnum++; } ins(x,y); } mes(match,0); ans=0;mes(v,0); for(int i=1;i<=n;i++){ v[0]++; if(findmuniu(i)==true){ ans++; } } if(ans==xlnum){ if(ans==ylnum)printf("Bob Win!\n"); else printf("Alice Win!\n"); } else{ if(ans==ylnum)printf("Alice Win!\n"); else printf("Bob Win!\n"); } } return 0; }下面的才是正解#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; const int Maxn = 1010; const int Maxm = 100010; struct node { int y, next; }a[Maxm]; int first[Maxn], len; void ins(int x, int y) { len++; a[len].y = y; a[len].next = first[x]; first[x] = len; } struct lnode { int x, y; }list[Maxm]; int b[Maxm], c[Maxm], bl, cl; int n, m, K; int T, v[Maxn], belong[Maxn]; bool fc(int x) { for(int k = first[x]; k; k = a[k].next){ int y = a[k].y; if(v[y] != T){ v[y] = T; if(!belong[y] || fc(belong[y])){ belong[y] = x; return true; } } } return false; } int main() { freopen("a.in", "r", stdin); freopen("a.out", "w", stdout); int i, j, k; int Ti; scanf("%d", &Ti); while(Ti--){ scanf("%d%d%d", &n, &m, &K); for(i = 1; i <= K; i++){ scanf("%d%d", &list[i].x, &list[i].y); b[i] = list[i].x; c[i] = list[i].y; } sort(b+1, b+K+1); bl = unique(b+1, b+K+1) - (b+1); sort(c+1, c+K+1); cl = unique(c+1, c+K+1) - (c+1); if(bl != cl){ printf("Alice Win!\n"); continue; } len = 0; memset(first, 0, sizeof(first)); for(i = 1; i <= K; i++){ int x = lower_bound(b+1, b+bl+1, list[i].x) - b; int y = lower_bound(c+1, c+cl+1, list[i].y) - c; ins(x, y); } bool bk = true; memset(v, 0, sizeof(v)); memset(belong, 0, sizeof(belong)); for(T = 1; T <= bl; T++){ if(!fc(T)){ bk = false; break; } } if(bk == true) printf("Bob Win!\n"); else printf("Alice Win!\n"); } return 0; }然后好好比对了一下?wak,粗心看错了条件。 T2 T2的话是一题找规律,然而我不会,所以我还是会给std 然而std时用dp做的??(用dp找规律)#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <cmath> #define LL long long using namespace std; const LL Maxn = 1100; LL f[210][Maxn]; LL na[Maxn]; LL pr[210], prl; LL n; bool v[Maxn]; LL get_pr (){ memset ( v, false, sizeof (v) ); LL i, j; prl = 0; for ( i = 2; i <= 1000; i ++ ){ if ( v[i] == false ){ pr[++prl] = i; na[i] = prl; } for ( j = 1; j <= prl && i*pr[j] <= 1000; j ++ ){ v[i*pr[j]] = true; if ( i % pr[j] == 0 ) break; } } } int main (){ freopen("b.in", "r", stdin); freopen("b.out", "w", stdout); LL i, j, k; scanf ( "%lld", &n ); get_pr (); memset ( f, 0, sizeof (f) ); f[0][0] = 1; for ( i = 1; i <= prl; i ++ ){ for ( j = 0; j <= n; j ++ ){ f[i][j] += f[i-1][j]; for ( k = pr[i]; k <= j; k *= pr[i] ){ f[i][j] += f[i-1][j-k]; } } } LL ans = 0; for ( i = 0; i <= n; i ++ ) ans += f[prl][i]; printf ( "%lld\n", ans ); return 0; }T3 题目就是要求最小生成树啊,然后就从每个点开始bfs,记录每个格子是谁先到的,后面的人再到达就和他连一条边,再做最小生成树就很棒了 然而我还是不会。所以送上一个90P的vio#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; const int dx[4]={0,-1,0,1}; const int dy[4]={-1,0,1,0}; struct ac { int x,y,c,next; }e[410000];int tlen,last[210000]; void insx(int x,int y,int c){tlen++;e[tlen].x=x;e[tlen].y=y;e[tlen].c=c;e[tlen].next=last[x];last[x]=tlen;} struct node { int x,y,dep,op; }list[11100000];int head,tail; struct edge { int x,y,c; }a[16160400];int len; void ins(int x,int y,int c) { len++; a[len].x=x;a[len].y=y;a[len].c=c; } int v[2100][2100],d[2100][2100]; bool cmp(edge n1,edge n2){return n1.c<n2.c;} int h,w,p,q; bool vis[2100][2100]; char s[2100][2100]; int fa[210000]; int findfa(int x) { if(fa[x]!=x)fa[x]=findfa(fa[x]); return fa[x]; } int f[210000][22],dep[810000]; int maxn[210000][22]; void pre_tree_node(int x) { for(int i=1;i<=18;i++)f[x][i]=f[f[x][i-1]][i-1],maxn[x][i]=max(maxn[x][i-1],maxn[f[x][i-1]][i-1]); for(int k=last[x];k;k=e[k].next) { int y=e[k].y; if(y!=f[x][0]) { f[y][0]=x;maxn[y][0]=e[k].c; dep[y]=dep[x]+1; // printf("%d %d %d\n",e[k].x,e[k].y,e[k].c); pre_tree_node(y); } } } int getsum(int x,int y) { int ret=0; if(dep[x]<dep[y])swap(x,y); for(int i=17;i>=0;i--) if(dep[f[x][i]]>=dep[y])ret=max(ret,maxn[x][i]),x=f[x][i]; if(x==y)return ret; for(int i=17;i>=0;i--) if(f[x][i]!=f[y][i])ret=max(ret,max(maxn[x][i],maxn[y][i])),x=f[x][i],y=f[y][i]; return max(ret,max(maxn[x][0],maxn[y][0])); } int main() { scanf("%d%d%d%d",&h,&w,&p,&q); for(int i=1;i<=h;i++)scanf("%s",s[i]+1); memset(vis,true,sizeof(vis)); memset(v,0,sizeof(v)); head=1;tail=0; for(int i=1;i<=p;i++) { int x,y; scanf("%d%d",&x,&y); list[++tail].x=x;list[tail].y=y;list[tail].dep=0;list[tail].op=i; vis[x][y]=false;v[x][y]=i;d[x][y]=0; } while(head<=tail) { node tno=list[head]; for(int i=0;i<=3;i++) { node next=tno;next.x+=dx[i];next.y+=dy[i]; if(next.x>=1 && next.x<=h && next.y>=1 && next.y<=w) { if(vis[next.x][next.y]==true && s[next.x][next.y]!='#') { tail++; list[tail]=next;list[tail].dep=next.dep+1; v[next.x][next.y]=list[tail].op; d[next.x][next.y]=list[tail].dep; vis[next.x][next.y]=false; } else if(vis[next.x][next.y]==false && s[next.x][next.y]!='#' && v[next.x][next.y]!=v[tno.x][tno.y]) { ins(v[next.x][next.y],v[tno.x][tno.y],d[next.x][next.y]+d[tno.x][tno.y]); } } } head++; } sort(a+1,a+1+len,cmp); for(int i=1;i<=p;i++)fa[i]=i; int cnt=p;tlen=0;memset(last,0,sizeof(last)); for(int i=1;i<=len;i++) { int u=findfa(a[i].x),v=findfa(a[i].y); if(u!=v) { fa[u]=v; insx(a[i].x,a[i].y,a[i].c); insx(a[i].y,a[i].x,a[i].c); cnt--; if(cnt==1)break; } } // for(int i=1;i<=tlen;i+=2)printf("%d %d %d\n",e[i].x,e[i].y,e[i].c); for(int i=1;i<=p;i++) if(fa[i]==i) { dep[i]=1;pre_tree_node(i); } /* else { for(int i=1;i<=p;i++) if(fa[i]==i) { f[i]=0;dep[i]=0;dep_s[1]=0; pre_tree_node(i); } }*/ while(q--) { int x,y; scanf("%d%d",&x,&y); int u=findfa(x),v=findfa(y); if(u!=v){printf("-1\n");continue;} printf("%d\n",getsum(x,y)); } return 0; }然后再送上一个100p的std#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <queue> using namespace std; const int Maxn = 2010; const int Maxp = 200010; const int lg = 18; const int dx[4] = {0, -1, 0, 1}; const int dy[4] = {1, 0, -1, 0}; struct Point { int x, y; }; struct enode { int x, y, d; }list[Maxn*Maxn*4]; int l; bool cmp(enode x, enode y) { return x.d < y.d; } struct node { int y, next, d; }a[Maxp*2]; int first[Maxp], len; void ins(int x, int y, int d) { len++; a[len].y = y; a[len].d = d; a[len].next = first[x]; first[x] = len; } queue <Point> q; int n, m, P, Q; char s[Maxn][Maxn]; int num[Maxn][Maxn], dis[Maxn][Maxn]; int faa[Maxp]; int ff(int x) { return faa[x] == x ? x : faa[x] = ff(faa[x]); } int fa[Maxp][lg], Max[Maxp][lg], dep[Maxp]; int _max(int x, int y) { return x > y ? x : y; } void dfs(int x) { for(int i = 1; i < lg; i++) fa[x][i] = fa[fa[x][i-1]][i-1], Max[x][i] = _max(Max[x][i-1], Max[fa[x][i-1]][i-1]); for(int k = first[x]; k; k = a[k].next){ int y = a[k].y; if(y == fa[x][0]) continue; dep[y] = dep[x]+1; fa[y][0] = x; Max[y][0] = a[k].d; dfs(y); } } int getlca(int x, int y) { if(dep[x] < dep[y]) swap(x, y); int ret = 0; for(int i = lg-1; i >= 0; i--){ if(dep[fa[x][i]] >= dep[y]) ret = _max(ret, Max[x][i]), x = fa[x][i]; } if(x == y) return ret; for(int i = lg-1; i >= 0; i--){ if(fa[x][i] != fa[y][i]) ret = _max(ret, _max(Max[x][i], Max[y][i])), x = fa[x][i], y = fa[y][i]; } return _max(ret, _max(Max[x][0], Max[y][0])); } int main() { freopen("c.in", "r", stdin); freopen("c.out", "w", stdout); int i, j, k; scanf("%d%d%d%d", &n, &m, &P, &Q); for(i = 1; i <= n; i++) scanf("%s", s[i]+1); for(i = 1; i <= P; i++){ Point o; scanf("%d%d", &o.x, &o.y); num[o.x][o.y] = i; dis[o.x][o.y] = 0; q.push(o); } while(!q.empty()){ Point x = q.front(); q.pop(); for(k = 0; k < 4; k++){ Point y; y.x = x.x+dx[k]; y.y = x.y+dy[k]; if(y.x < 1 || y.x > n || y.y < 1 || y.y > m || s[y.x][y.y] == '#') continue; if(!num[y.x][y.y]){ num[y.x][y.y] = num[x.x][x.y]; dis[y.x][y.y] = dis[x.x][x.y]+1; q.push(y); } else if(num[x.x][x.y] != num[y.x][y.y]){ l++; list[l].x = num[x.x][x.y]; list[l].y = num[y.x][y.y]; list[l].d = dis[x.x][x.y]+dis[y.x][y.y]; } } } for(i = 1; i <= P; i++) faa[i] = i; sort(list+1, list+l+1, cmp); for(i = 1; i <= l; i++){ int fx = ff(list[i].x), fy = ff(list[i].y); if(fx != fy){ faa[fx] = fy; ins(list[i].x, list[i].y, list[i].d); ins(list[i].y, list[i].x, list[i].d); } } for(i = 1; i <= P; i++){ if(faa[i] == i) dep[i] = 1, dfs(i); } for(i = 1; i <= Q; i++){ int x, y; scanf("%d%d", &x, &y); int fx = ff(x), fy = ff(y); if(fx != fy){ printf("-1\n"); continue; } printf("%d\n", getlca(x, y)); } return 0; }
查看原文:http://hz2016.cn/blog/?p=115
【训练】2017-11-6晚
最新推荐文章于 2021-03-22 20:39:33 发布