【训练】2017-11-6晚

来源:互联网 发布:cocos2d-js 编辑:程序博客网 时间:2024/06/07 13:44
T1T1的话是一个明显得不能再明显得二分图匹配,然而我少判断了一组情况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,粗心看错了条件。T2T2的话是一题找规律,然而我不会,所以我还是会给std然而std时用dp做的??(用dp找规律)
#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <cmath>#define LL long longusing 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
原创粉丝点击