2012杭州现场赛

来源:互联网 发布:mac应用下载网站 编辑:程序博客网 时间:2024/04/30 06:05

Outlets

看一眼就应该知道是要求MST。

#include <stdio.h>#include <string.h>#include <math.h>#include <algorithm>using namespace std;const int N=10000;struct DST{    int father[N];    void init()    {        for (int i=0; i<N; i++) father[i]=i;    }    int root(int k)    {        if (father[k]==k) return k;        father[k]=root(father[k]);        return father[k];    }    void merge(int x, int y)    {        x=root(x),y=root(y);        father[x]=father[y];    }}s;struct _point{    int x,y;    double d;}site[60],edge[N];inline bool cmp(const _point &a, const _point &b){    return (a.d<b.d);}int main(){    int i,j,k,n,p,q,x,y,K;    double tot;    while (scanf("%d",&n),n)    {        s.init();        scanf("%d %d",&p, &q);        for (i=1; i<=n; i++)        {            scanf("%d %d",&site[i].x,&site[i].y);        }        for (i=1,k=0; i<=n; i++)          for (j=1; j<=n; j++)          if (i!=j)          {            edge[k].d=sqrt(                (site[i].x-site[j].x)*(site[i].x-site[j].x)                +(site[i].y-site[j].y)*(site[i].y-site[j].y)+0.0);            edge[k].x=i, edge[k].y=j;            k++;          }        K=k;        sort(edge,edge+K,cmp);        tot=sqrt(                (site[p].x-site[q].x)*(site[p].x-site[q].x)                +(site[p].y-site[q].y)*(site[p].y-site[q].y)+0.0);        s.merge(p,q);        for (i=1,k=2; k<n; i++)        {            x=edge[i].x, y=edge[i].y;            x=s.root(x), y=s.root(y);            if (x==y) continue;            s.merge(x,y);            tot+=edge[i].d;            k++;        }        printf("%.2f\n",tot);    }    return 0;}


 

Friend Chains

点V=1000,边E=10000,floyd不靠谱,单点最短路径bfs的复杂度是O(V+E),跑V次O(V^2+VE),可以接受,水过。

那个名字用map来hash就好了

#include <stdio.h>#include <string.h>#include <string>#include <map>using namespace std;const int V = 1010;const int E = 25010;int n;int g[V][V],cnt;struct node{    int x,y,w;    node *next;}edge[E],*head[V];inline void addedge(int x, int y, int w){    edge[cnt].x=x, edge[cnt].y=y, edge[cnt].w=w;    edge[cnt].next=head[x]; head[x]=edge+cnt++;}void init(){    cnt=0;    memset(head,0,sizeof(head));    memset(g,0,sizeof(g));}int q[V],vis[V],dis[V];int bfs(int st){    int he,ta,now;//head tail    he=1,ta=0;    memset(vis,0,sizeof(vis));    memset(dis,7,sizeof(dis));    q[0]=st;    vis[st]=true;    dis[st]=0;    while (ta<he){        now=q[ta++];        //vis[now]=true;//useless        for (node* p=head[now]; p; p=p->next){            if (!vis[p->y] && dis[p->y]>dis[now]+p->w)            {                q[he++]=p->y;                vis[p->y]=true;                dis[p->y]=dis[now]+p->w;            }        }    }    int i,max=0;    for (i=0; i<n; i++)      if (dis[i]>max) max=dis[i];    return max;}int main(){    map<string,int> name;    char str[11],s1[11],s2[11];    int m,i,j,k,x,y;    while ( scanf("%d",&n),n){        init();        name.clear();        k=0;        for (i=0; i<n; i++)        {            scanf("%s",str);            name[str]=i;        }        scanf("%d",&m);        for (i=0; i<m; i++)        {            scanf("%s %s",s1,s2);            x=name[s1], y=name[s2];            g[x][y]=g[y][x]=1;        }        for (i=0; i<n; i++)         for (j=0; j<n; j++)          if (g[i][j]) addedge(i,j,1);        int tmp;        for (i=0,k=0; i<n; i++)        {            tmp=bfs(i);            if (tmp>k) k=tmp;            if (k>=n) break;        }        if (k>=n) k=-1;        printf("%d\n",k);    }    return 0;}

Scaring the Birds

这题二分稻草人的数量,dfs枚举稻草人的组合,然后验证即可。

n似乎不大,直接用循环赋值应该就能A,用线段树求覆盖长度是在干嘛。。。
 

#include <cstdio>#include<cstring>using namespace std;#define L(u) ( u << 1 )#define R(u) ( u << 1 | 1 )#define N 55struct item{ int l, r; int v, add;};struct tree{    item node[N*3];    int num[N];    int n, q;    void init ( int u, int l, int r )    {        node[u].l = l;        node[u].r = r;        node[u].v = 0;        node[u].add = 0;        if ( l == r ) return;        int mid = ( l + r ) >> 1;        init ( L(u), l, mid );        init ( R(u), mid+1, r );    }    int set ( int u, int l, int r)    {        int ret = 0;        if ( node[u].v ==  node[u].r-node[u].l+1 ) return 0;        if ( l == node[u].l && node[u].r == r ) {            ret = r-l+1-node[u].v;            node[u].v = r-l+1;            return ret;        }        int mid = ( node[u].l + node[u].r ) >> 1;        if ( r <= mid )            ret = set ( L(u), l, r );        else if ( l > mid )            ret = set ( R(u), l, r );        else {            ret = set ( L(u), l, mid );            ret+= set ( R(u), mid+1, r );        }        node[u].v += ret;        return ret;    }    int sum ( int u, int l, int r )    {        if ( node[u].v ==  node[u].r-node[u].l+1 ) return r-l+1;        if ( l == node[u].l && node[u].r == r ) {            return node[u].v;        }        int mid = ( node[u].l + node[u].r ) >> 1;        if ( r <= mid )            return sum ( L(u), l, r );        else if ( l > mid )            return sum ( R(u), l, r );        else            return (sum ( L(u), l, mid ) + sum ( R(u), mid+1, r ));    }}s[N];struct Vac{    int x,y,r,vis;}V[N];bool check(int n, int k, int mid){    int i,j,l,r,p;    for (i=1; i<=n; i++) s[i].init(1,1,n);    for (i=0; i<k; i++){      s[ V[i].y ].set(1, V[i].x, V[i].x);      if (V[i].vis) {        for (j=0; j<=V[i].r; j++){            l=V[i].x-(V[i].r-j), r=V[i].x+V[i].r-j;            if (l<=0) l=1;            if (r>=n) r=n;            p=V[i].y-j;            if (p>=1) s[p].set(1,l,r);            p=V[i].y+j;            if (p<=n) s[p].set(1,l,r);        }      }    }    for (i=1, j=0; i<=n; i++) j+=s[i].sum(1,1,n);    if (j==n*n) return true; else return false;}bool dfs(int n,int k, int d, int mid, int p){    if (d==mid){        return check(n,k,mid);    }    bool tmp;    for (int i=p; i<k; i++){        if (V[i].vis==0){            V[i].vis=1;            tmp=dfs(n,k,d+1,mid,i+1);            V[i].vis=0;            if (tmp) return true;        }    }    return false;}int solve(int n, int k){    int l,r,mid;    l=0, r=k+1;    while (l<r){        mid=(l+r)>>1;        if ( dfs(n,k,0,mid,0) ) r=mid; else l=mid+1;    }    if (l==k+1) return -1; else return l;}int main(){    int i,k,n;    while ( scanf("%d",&n), n ){        scanf("%d",&k);        for (i=0; i<k; i++) scanf("%d %d",&V[i].x,&V[i].y);        for (i=0; i<k; i++) scanf("%d",&V[i].r);        printf("%d\n",solve(n,k));    }    return 0;}


 

 

 

 

 

 

 

 

 

原创粉丝点击