zoukankan      html  css  js  c++  java
  • 2010 Asia Tianjin Regional Contest

    1001 Arranging Your Team

    直接暴力枚举所有情况。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 map<string,int> mp1;
     4 map<string,int> mp2;
     5 struct node{
     6     int name,val,pos;
     7 } a[55];
     8 int n;
     9 int ans;
    10 int b[55][55];
    11 int va;
    12 string na,po;
    13 
    14 int vis[55];
    15 void dfs(int now,int n1,int n2,int n3,int n4){
    16     if(now>24) return;
    17     if(n1>1||n2>4||n3>4||n4>2) return;
    18     if(n1==1&&n2==4&&n3==4&&n4==2){
    19         int tmp=0;
    20         for(int i=1;i<=23;i++){
    21             if(vis[i]) {
    22                 tmp+=a[i].val;
    23                 for(int j=i+1;j<=23;j++){
    24                     if(vis[j]) tmp+=b[i][j];
    25                 }
    26             }
    27         }
    28         ans=max(ans,tmp);
    29         return;
    30     }
    31 
    32     vis[now]=1;
    33     if(a[now].pos==1) dfs(now+1,n1+1,n2,n3,n4);
    34     else if(a[now].pos==2) dfs(now+1,n1,n2+1,n3,n4);
    35     else if(a[now].pos==3) dfs(now+1,n1,n2,n3+1,n4);
    36     else if(a[now].pos==4) dfs(now+1,n1,n2,n3,n4+1);
    37     vis[now]=0;
    38 
    39     dfs(now+1,n1,n2,n3,n4);
    40 
    41     return;
    42 }
    43 
    44 int main(){
    45     mp2["goalkeeper"]=1;
    46     mp2["defender"]=2;
    47     mp2["midfielder"]=3;
    48     mp2["striker"]=4;
    49     while(cin>>na>>va>>po){
    50         memset(vis,0,sizeof(vis));
    51         memset(b,0,sizeof(b));
    52         ans=-10000000;
    53         mp1.clear();
    54 
    55         mp1[na]=1;
    56         a[1].name=1;
    57         a[1].val=va;
    58         a[1].pos=mp2[po];
    59         for(int i=2;i<=23;i++){
    60             cin>>na>>va>>po;
    61             mp1[na]=i;
    62             a[i].name=i;
    63             a[i].val=va;
    64             a[i].pos=mp2[po];
    65         }
    66         int m;
    67         scanf("%d",&m);
    68         for(int i=1;i<=m;i++){
    69             cin>>na>>po>>va;
    70             b[mp1[na]][mp1[po]]=va;
    71             b[mp1[po]][mp1[na]]=va;
    72         }
    73 
    74         dfs(1,0,0,0,0);
    75         if(ans==-10000000) printf("impossible
    ");
    76         else printf("%d
    ",ans);
    77     }
    78 
    79     return 0;
    80 }
    Psong

    1002 Building Roads

    所拆除的边一定是在树的直径上,枚举这些边,每次拆成两棵树,将两棵树中心相连即可,取两棵树直径和中心相连后三个长度的最大值。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int inf=0x3f3f3f3f;
      4 struct node{
      5     int v,w;
      6 };
      7 vector<node> g[3005];
      8 void addedge(int u,int v,int w){
      9     g[u].push_back((node){v,w});
     10     g[v].push_back((node){u,w});
     11 }
     12 struct node2{
     13     int u,v,w;
     14 };
     15 vector<node2> e[3005];
     16 int n;
     17 int dis[3005];
     18 int vis[3005];
     19 int deep[3005];
     20 int SPFA(int s,int lim){
     21     memset(vis,0,sizeof(vis));
     22     memset(dis,inf,sizeof(dis));
     23     int ans=s,res=0;
     24     queue<int> q;
     25     q.push(s);
     26     dis[s]=0; vis[s]=1;
     27     while(!q.empty()){
     28         int u=q.front();
     29         q.pop(); vis[u]=0;
     30         if(dis[u]>res) res=dis[u],ans=u;
     31         for(int i=0;i<g[u].size();i++){
     32             int v=g[u][i].v;
     33             int w=g[u][i].w;
     34             if(v==lim) continue;
     35             if(dis[u]+w<dis[v]){
     36                 dis[v]=dis[u]+w;
     37                 if(!vis[v]){
     38                     q.push(v);
     39                     vis[v]=1;
     40                 }
     41             }
     42         }
     43     }
     44     return ans;
     45 }
     46 int head,tail;
     47 bool dfs1(int u,int fa,int ss){
     48     int flag=0;
     49     for(int i=0;i<g[u].size();i++){
     50         int v=g[u][i].v;
     51         int w=g[u][i].w;
     52         if(v==fa) continue;
     53         if(dfs1(v,u,ss)){
     54             e[1].push_back((node2){v,u,w});
     55             return true;
     56         }
     57     }
     58     if(u==ss) return true;
     59     return false;
     60 }
     61 void dfs2(int u,int fa,int d){
     62     deep[u]=d;
     63     for(int i=0;i<g[u].size();i++){
     64         int v=g[u][i].v;
     65         int w=g[u][i].w;
     66         if(v==fa) continue;
     67         dfs2(v,u,d+1);
     68     }
     69 }
     70 void dfs3(int u,int T,int fa,int lim,int d){
     71     dis[u]=max(dis[u],d);
     72     for(int i=0;i<g[u].size();i++){
     73         int v=g[u][i].v;
     74         int w=g[u][i].w;
     75         if(v==lim) continue;
     76         if(v==fa) continue;
     77         dfs3(v,T,u,lim,d+w);
     78     }
     79 }
     80 int fun(int S,int T,int lim,int &tmp){
     81     tmp=0;
     82     memset(dis,-1,sizeof(dis));
     83     dis[S]=0;
     84     dfs3(S,T,0,lim,0);
     85     dfs3(T,S,0,lim,0);
     86     int res=inf;
     87     for(int i=1;i<=n;i++) {
     88         if(dis[i]!=-1) res=min(res,dis[i]);
     89         tmp=max(dis[i],tmp);
     90     }
     91     return res;
     92 }
     93 int solve(int u,int v,int w){
     94     int res=w;
     95     int tmp1;
     96     int head1=SPFA(u,v);
     97     int tail1=SPFA(head1,v);
     98     res+=fun(head1,tail1,v,tmp1);
     99     int tmp2;
    100     int head2=SPFA(v,u);
    101     int tail2=SPFA(head2,u);
    102     res+=fun(head2,tail2,u,tmp2);
    103     res=max(res,tmp1);
    104     res=max(res,tmp2);
    105     return res;
    106 }
    107 int main(){
    108     int t;
    109     scanf("%d",&t);
    110     int T=t;
    111     while(t--){
    112         scanf("%d",&n);
    113         for(int i=1;i<=n;i++) g[i].clear();
    114         for(int i=1;i<=n;i++) e[i].clear();
    115         for(int i=1;i<n;i++){
    116             int x,y,z;
    117             scanf("%d%d%d",&x,&y,&z);
    118             addedge(x+1,y+1,z);
    119         }
    120         head=SPFA(1,0); tail=SPFA(head,0);
    121         deep[1]=1; dfs2(1,0,1); dfs1(head,0,tail);
    122         int ans=inf;
    123         for(int i=0;i<e[1].size();i++)
    124             ans=min(ans,solve(e[1][i].u,e[1][i].v,e[1][i].w));
    125         printf("Case %d: %d
    ",T-t,ans);
    126     }
    127 
    128     return 0;
    129 }
    Psong

    1003 Card Game

    最大费用流。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int inf=0x3f3f3f3f;
     4 struct edge{
     5     int to,cap,cost,rev;
     6 };
     7 vector<edge> g[1000005];
     8 int V;
     9 int dis[1000005],vis[1000005];
    10 int prevv[1000005],preve[1000005];
    11 void addedge(int from,int to,int cap,int cost){
    12     g[from].push_back((edge){to,cap,cost,g[to].size()});
    13     g[to].push_back((edge){from,0,-cost,g[from].size()-1});
    14 }
    15 void SPFA(int s,int t){
    16     fill(dis,dis+V,inf);
    17     fill(vis,vis+V,0);
    18     dis[s]=0; vis[s]=1;
    19     queue<int> q;
    20     q.push(s);
    21     while(!q.empty()){
    22         int v=q.front();
    23         q.pop();
    24         vis[v]=0;
    25         for(int i=0;i<g[v].size();i++){
    26             edge &e=g[v][i];
    27             if(e.cap>0&&dis[e.to]>dis[v]+e.cost){
    28                 dis[e.to]=dis[v]+e.cost;
    29                 prevv[e.to]=v;
    30                 preve[e.to]=i;
    31                 vis[e.to]=1;
    32                 q.push(e.to);
    33             }
    34         }
    35     }
    36 }
    37 int min_cost_flow(int s,int t,int f){
    38     int res=0;
    39     while(f>0){
    40         SPFA(s,t);
    41         if(dis[t]==inf) return -1;
    42         int d=f;
    43         for(int v=t;v!=s;v=prevv[v]){
    44             d=min(d,g[prevv[v]][preve[v]].cap);
    45         }
    46         f-=d;
    47         res+=d*dis[t];
    48         for(int v=t;v!=s;v=prevv[v]){
    49             edge &e=g[prevv[v]][preve[v]];
    50             e.cap-=d;
    51             g[v][e.rev].cap+=d;
    52         }
    53     }
    54     return res;
    55 }
    56 int n;
    57 int val[205][205];
    58 string s[205];
    59 int solve(string s1,string s2){
    60     int cnt=0;
    61     int L=s1.size()-1,R=0;
    62     while(L>=0&&R<s2.size()){
    63         if(s1[L]==s2[R]) cnt++;
    64         else break;
    65         L--,R++;
    66     }
    67     return cnt;
    68 }
    69 int main(){
    70     while(cin>>n){
    71         for(int i=1;i<=n;i++) cin>>s[i];
    72         for(int i=1;i<=n;i++)
    73         for(int j=1;j<=n;j++){
    74             if(i==j) val[i][j]=0;
    75             else val[i][j]=solve(s[i],s[j]);
    76         }
    77         V=n+n+2;
    78         for(int i=0;i<V;i++) g[i].clear();
    79         for(int i=1;i<=n;i++){
    80             addedge(0,i,1,0);
    81             addedge(i+n,n+n+1,1,0);
    82         }
    83         for(int i=1;i<=n;i++)
    84         for(int j=1;j<=n;j++){
    85             addedge(i,j+n,1,-val[i][j]);
    86         }
    87         printf("%d
    ",-min_cost_flow(0,n+n+1,n));
    88     }
    89 
    90     return 0;
    91 }
    Psong

    1004 Delta Wave

    1005 Encoded Barcodes

    先把所有商品字符串存入字典树。对于每个条形码,取最大值,然后判断每个数是0还是1。匹配的时候跑一遍字典树。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int cnt;
     4 struct Trie{
     5     int Next[35];
     6     int ok;
     7 } trie[100005];
     8 void add(char s[],int p,int len){
     9     for(int i=0;i<len;i++){
    10         if(trie[p].Next[s[i]-'a']==0){
    11             trie[p].Next[s[i]-'a']=++cnt;
    12         }
    13         p=trie[p].Next[s[i]-'a'];
    14         trie[p].ok++;
    15     }
    16 }
    17 int query(char s[],int p,int len){
    18     for(int i=0;i<len;i++){
    19         if(trie[p].Next[s[i]-'a']==0) return 0;
    20         p=trie[p].Next[s[i]-'a'];
    21     }
    22     return trie[p].ok;
    23 }
    24 int n,m,k;
    25 double a[10];
    26 char s[10005][35];
    27 int pp[]={1,2,4,8,16,32,64,128,256,512};
    28 char fun(){
    29     double ma=a[1];
    30     for(int i=1;i<=8;i++) ma=max(ma,a[i]);
    31     ma/=1.5;
    32     int res=0;
    33     for(int i=1;i<=8;i++){
    34         int now=a[i]<ma?0:1;
    35         res=((res<<1)|now);
    36     }
    37     return res;
    38 }
    39 int tot;
    40 char tmp[35];
    41 int main(){
    42     while(~scanf("%d%d",&n,&m)){
    43         cnt=0;
    44         memset(trie,0,sizeof(trie));
    45         for(int i=1;i<=n;i++) {
    46             scanf("%s",s[i]);
    47             int len=strlen(s[i]);
    48             add(s[i],0,len);
    49         }
    50         int ans=0;
    51         for(int i=1;i<=m;i++){
    52             tot=0;
    53             scanf("%d",&k);
    54             for(int j=1;j<=k;j++){
    55                 for(int p=1;p<=8;p++) scanf("%lf",&a[p]);
    56                 tmp[tot++]=fun();
    57             }
    58             ans+=query(tmp,0,tot);
    59             //cout<<"ans="<<ans<<endl;
    60         }
    61         printf("%d
    ",ans);
    62     }
    63 
    64     return 0;
    65 }
    Psong

    1006 Farm

    1007 Graph and Queries

    1008 Jewel

    主席树模板题。(直接把所有int改long long MLE了。。。)

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef long long LL;
      4 const int N=200005;
      5 int n,m,cnt,tot;
      6 int T[N],a[N];
      7 struct node{
      8     int l,r,sum;
      9 } tre[N*40];
     10 int c[N];
     11 int lowbit(int x){
     12     return x&(-x);
     13 }
     14 void add(int pos,int val){
     15     for(int i=pos;i<=n;i+=lowbit(i))
     16         c[i]+=val;
     17 }
     18 int sum(int pos){
     19     int res=0;
     20     for(int i=pos;i>0;i-=lowbit(i))
     21         res+=c[i];
     22     return res;
     23 }
     24 void update(int l,int r,int &x,int y,int pos){
     25     tre[++cnt]=tre[y];
     26     tre[cnt].sum++;
     27     x=cnt;
     28     if(l==r) return;
     29     int mid=(l+r)/2;
     30     if(mid>=pos)
     31         update(l,mid,tre[x].l,tre[y].l,pos);
     32     else
     33         update(mid+1,r,tre[x].r,tre[y].r,pos);
     34 }
     35 int query(int l,int r,int x,int y,int k){
     36     if(l==r) return l;
     37     int mid=(l+r)/2;
     38     int sum=tre[tre[y].l].sum-tre[tre[x].l].sum;
     39     if(sum>=k)
     40         return query(l,mid,tre[x].l,tre[y].l,k);
     41     else
     42         return query(mid+1,r,tre[x].r,tre[y].r,k-sum);
     43 
     44 }
     45 vector<int> v;
     46 int getid(int x){
     47     return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
     48 }
     49 struct Query{
     50     int op,x,y,z;
     51 } que[200005];
     52 int main(){
     53     int Case=0;
     54     while(~scanf("%d",&m)){
     55         Case++;
     56         v.clear();
     57         tot=cnt=0;
     58         memset(c,0,sizeof(c));
     59         LL ans1=0,ans2=0,ans3=0;
     60         for(int i=1;i<=m;i++){
     61             char tmp[15];
     62             int x,y,z;
     63             scanf("%s",tmp);
     64             if(!strcmp(tmp,"Insert")){
     65                 que[i].op=1;
     66                 scanf("%d",&que[i].x);
     67                 v.push_back(que[i].x);
     68             }
     69             if(!strcmp(tmp,"Query_1")){
     70                 que[i].op=2;
     71                 scanf("%d%d%d",&que[i].x,&que[i].y,&que[i].z);
     72             }
     73             if(!strcmp(tmp,"Query_2")){
     74                 que[i].op=3;
     75                 scanf("%d",&que[i].x);
     76             }
     77             if(!strcmp(tmp,"Query_3")){
     78                 que[i].op=4;
     79                 scanf("%d",&que[i].x);
     80             }
     81         }
     82         sort(v.begin(),v.end());
     83         v.erase(unique(v.begin(),v.end()),v.end());
     84         n=v.size();
     85         for(int i=1;i<=m;i++){
     86             if(que[i].op==1){
     87                 tot++;
     88                 add(getid(que[i].x),1);
     89                 update(1,n,T[tot],T[tot-1],getid(que[i].x));
     90             }
     91             if(que[i].op==2){
     92                 ans1+=v[query(1,n,T[que[i].x-1],T[que[i].y],que[i].z)-1];
     93             }
     94             if(que[i].op==3){
     95                 ans2+=sum(getid(que[i].x)-1)+1;
     96             }
     97             if(que[i].op==4){
     98                 ans3+=v[query(1,n,T[0],T[tot],que[i].x)-1];
     99             }
    100         }
    101 
    102         printf("Case %d:
    ",Case);
    103         printf("%lld
    ",ans1);
    104         printf("%lld
    ",ans2);
    105         printf("%lld
    ",ans3);
    106     }
    107 
    108     return 0;
    109 }
    Psong

    1009 Hyperspace Travel

    1010 I'm Telling the Truth

    二分图匹配,因为要求字典序最大,所以匹配时从后往前匹配即可。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int V,n;
     4 int x,y;
     5 vector<int> g[111111];
     6 int vis[111111],match[111111];
     7 void addedge(int u,int v){
     8     g[u].push_back(v);
     9     g[v].push_back(u);
    10 }
    11 bool dfs(int u){
    12     vis[u]=1;
    13     for(int i=0;i<g[u].size();i++){
    14         int v=g[u][i],w=match[v];
    15         if(w<0 || !vis[w] && dfs(w)){
    16             match[v]=u;
    17             match[u]=v;
    18             return true;
    19         }
    20     }
    21     return false;
    22 }
    23 int hungarian(){
    24     int res=0;
    25     memset(match,-1,sizeof(match));
    26     for(int u=V-1;u>=0;u--){
    27         if(match[u]<0){
    28             memset(vis,0,sizeof(vis));
    29             if(dfs(u)) res++;
    30         }
    31     }
    32     return res;
    33 }
    34 int main(){
    35     int t;
    36     scanf("%d",&t);
    37     while(t--){
    38         for(int i=0;i<110000;i++)
    39             g[i].clear();
    40         scanf("%d",&n);
    41         for(int i=1;i<=n;i++){
    42             scanf("%d%d",&x,&y);
    43             for(int j=x;j<=y;j++){
    44                 addedge(i-1,j+n-1);
    45             }
    46         }
    47         V=n;
    48         hungarian();
    49         vector<int> ans;
    50         for(int i=0;i<n;i++){
    51             if(match[i]!=-1) ans.push_back(i+1);
    52         }
    53         printf("%d
    ",ans.size());
    54         for(int i=0;i<ans.size();i++){
    55             printf("%d",ans[i]);
    56             if(i==ans.size()-1) printf("
    ");
    57             else printf(" ");
    58         }
    59     }
    60 
    61     return 0;
    62 }
    Psong
  • 相关阅读:
    6-1
    4-9
    4-5
    4-4
    4-3
    3-10
    作业三2
    作业三1
    课堂练习二
    实验三
  • 原文地址:https://www.cnblogs.com/N-Psong/p/7196536.html
Copyright © 2011-2022 走看看