zoukankan      html  css  js  c++  java
  • 百度之星初赛b

    hdu6114

    推一下发现是求c(n,m),范围很小直接预处理递推

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int mod=1e9+7;
     4 const int maxn=1008;
     5 int c[maxn][maxn];
     6 void init()
     7 {
     8     memset(c,0,sizeof(c));
     9     c[0][0]=1;
    10     for(int i=1;i<=1000;i++)
    11         for(int j=0;j<=i;j++)
    12             c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
    13 }
    14 int main()
    15 {
    16     int t;
    17     scanf("%d",&t);
    18     init();
    19     int n,m;
    20     while(t--)
    21     {
    22         scanf("%d%d",&n,&m);
    23         if(n>m)
    24         {
    25             int temp=n;
    26             n=m;
    27             m=temp;
    28         }
    29         printf("%d
    ",c[m][n]);
    30     }
    31     return 0;
    32  } 

     hdu6115

    可以转化为求lca问题。(为什么我做过的lca题时限都这么鬼畜呢,我以后永远选择树上倍增)

    lca:求两个节点的最近公共祖先,一般有如下三种方法:

    树上倍增算法:先将两个点移到同一高度,再让他们一起往上爬,直到相遇。对爬的过程进行了优化:建立一系列向上爬2^0高度,2^1,...2^n高度的边,使得点可以沿这些边加速爬来接近目标。可以用求树的重心法优化

    tarjan算法:将所有询问离线处理,通过花式标记+简单并查集处理(个人认为这个方法是真的鬼畜,因为标记不少,又要维护集合,使得代码实际跑的速度比理论复杂度要大,常常出现O(n)跑不过O(nlogn)的情况,表示束手无策)

    树刨+rmq:按照dfs序处理一条2n长的链,使得链中公共祖先一定在任意两个子节点的中间。然后rmq维护之,查询其中深度最小的点(表示非常蛋疼)

    总之求lca是不难的,难点就在卡时间。就算用到了上述算法,但实现不够优秀,一样会t一脸。也不能说是被故意卡掉的,实在是rmq的测试数据都太大了,点多边多询问多,不小心可能连标程都卡掉这样子。。。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int N = 100010, INF = 0x3f3f3f3f;
     6 struct edge
     7 {
     8     int to, cost, next;
     9 }g[N*2];
    10 int cnt, head[N];
    11 int dep[N];
    12 int dis[N], p[N][20+5];
    13 bool vis[N];
    14 
    15 int n, m;
    16 vector<int> vec[N];
    17 void init()
    18 {
    19     cnt=0;
    20     memset(head,-1,sizeof(head));
    21 }
    22 void add_edge(int v, int u, int cost)
    23 {
    24     g[cnt].to = u, g[cnt].cost = cost, g[cnt].next = head[v], head[v] = cnt++;
    25 }
    26 void dfs(int v, int fa, int cost)
    27 {
    28     dis[v] = cost;
    29     for(int i = head[v]; i != -1; i = g[i].next)
    30     {
    31         int u = g[i].to;
    32         if(u == fa) continue;
    33         if(! dep[u])
    34             dep[u] = dep[v] + 1, p[u][0] = v, dfs(u, v, dis[v] + g[i].cost);
    35     }
    36 }
    37 void init1()
    38 {
    39     for(int j = 1; (1<<j) <= n; j++)
    40         for(int i = 1; i <= n; i++)
    41             p[i][j] = p[p[i][j-1]][j-1];
    42 }
    43 int LCA(int v, int u)
    44 {
    45     if(dep[v] < dep[u]) swap(v, u);
    46     int d = dep[v] - dep[u];
    47     for(int i = 0; (d>>i) != 0; i++)
    48         if((d>>i) & 1) v = p[v][i];
    49     if(v == u) return v;
    50     for(int i = 20; i >= 0; i--)
    51         if(p[v][i] != p[u][i]) v = p[v][i], u = p[u][i];
    52     return p[v][0];
    53 }
    54 int main()
    55 {
    56     int t, q;
    57     scanf("%d", &t);
    58     while(t--)
    59     {
    60         init();
    61         scanf("%d%d", &n, &m);
    62         for(int i = 1; i < n; i++)
    63         {
    64             int a, b, c;
    65             scanf("%d%d%d", &a, &b, &c);
    66             add_edge(a, b, c), add_edge(b, a, c);
    67         }
    68         for(int i = 1; i <= m; i++)
    69         {
    70             int num, v;
    71             scanf("%d", &num);
    72             for(int j = 1; j <= num; j++)
    73             {
    74                 scanf("%d", &v);
    75                 vec[i].push_back(v);
    76             }
    77         }
    78         memset(dis, 0, sizeof dis);
    79         memset(dep, 0, sizeof dep);
    80         dfs(1, 0, 0);
    81         init1();
    82         scanf("%d", &q);
    83         for(int i = 1; i <= q; i++)
    84         {
    85             int v, u, ans = INF;
    86             scanf("%d%d", &v, &u);
    87             for(size_t j = 0; j < vec[v].size(); j++)
    88                 for(size_t k = 0; k < vec[u].size(); k++)
    89                     ans = min(ans, dis[vec[v][j]] + dis[vec[u][k]] - dis[LCA(vec[v][j], vec[u][k])] * 2);
    90             printf("%d
    ", ans);
    91         }
    92         for(int i = 1; i <= m; i++) vec[i].clear();
    93     }
    94     return 0;
    95 }

     hdu6118

    费用流模板题,理解费用流就很容易a了。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=508;
    const int maxm=1008;
    const int INF=0x3f3f3f3f;
    struct fuck{
        int u,v,cap,cost,next;
    }edge[maxm<<4];
    int head[maxn];
    int dis[maxn],pre[maxn],vis[maxn];
    int tol;
    int n;
    void init()
    {
        tol=0;
        memset(head,-1,sizeof(head));
    }
    void addedge(int u,int v,int w,int c)
    {
        edge[tol].u=u;
        edge[tol].v=v;
        edge[tol].cap=c;
        edge[tol].cost=w;
        edge[tol].next=head[u];
        head[u]=tol++;
        edge[tol].u=v;
        edge[tol].v=u;
        edge[tol].cap=0;
        edge[tol].cost=-w;
        edge[tol].next=head[v];
        head[v]=tol++;
    }
    bool spfa()
    {
        queue<int>    q;
        q.push(0);
        memset(dis,INF,sizeof(dis));
        memset(vis,false,sizeof(vis));
        dis[0]=0;vis[0]=true;pre[0]=-1;
        int i,u,v;
        while(!q.empty())
        {
            u=q.front();q.pop();
            vis[u]=false;
            for(i=head[u];i!=-1;i=edge[i].next)
            {
                v=edge[i].v;
                if(edge[i].cap>0&&dis[v]>dis[u]+edge[i].cost)
                {
                    dis[v]=dis[u]+edge[i].cost;
                    pre[v]=i;
                    if(!vis[v])    
                    {
                        vis[v]=true;
                        q.push(v);
                    }
                }
            }
        }
        if(dis[n]>=INF)    return false;
        return true;
    }
    int min_costflow()
    {
        int co,fl,u,i;
        co=fl=0;
        while(spfa())
        {
            int mi=INF;
            for (i = pre[n]; i != -1; i = pre[edge[i ^ 1].v]) {  
                if (mi > edge[i].cap)  
                    mi = edge[i].cap;  
            }  
            for (i = pre[n]; i != -1; i = pre[edge[i ^ 1].v]) {  
                edge[i].cap -= mi;  
                edge[i ^ 1].cap += mi;   
            }  
            fl+=mi;
            if(dis[n]>0)    break;
            co +=mi*dis[n];
        }
        return co;
    }
    int main()
    {
        int m,u,v,a,b,c,d,w;
        while(scanf("%d%d",&n,&m)==2)
        {
            init();
            for(int i=1;i<=n;i++)
            {
                scanf("%d%d%d%d",&a,&b,&c,&d);
                addedge(0,i,a,b);
                addedge(i,n+1,-c,d);
            }
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                addedge(u,v,w,INF);
                addedge(v,u,w,INF);
            }
            n++;
            printf("%d
    ",-min_costflow());
        }
        return 0;
    }

    hdu6119

    先合并一样区间,然后二分就可以了

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=100008;
     4 struct fuck{
     5     int l,r;
     6 }f[maxn],g[maxn];
     7 int cmp(fuck a,fuck b)
     8 {
     9     if(a.l!=b.l)
    10         return a.l<b.l;
    11     return a.r<b.r;
    12 }
    13 int idx;
    14 void init(int n)
    15 {
    16     int i=1,j=i+1;
    17     idx=0;
    18     while(i<=n)
    19     {
    20         g[++idx]=f[i];
    21         while(j<=n)
    22         {
    23             if(f[j].l<=g[idx].r)
    24             {
    25                 g[idx].r=max(f[j].r,g[idx].r);
    26                 j++;
    27             }
    28             else
    29                 break;
    30         }
    31         i=j;
    32     }
    33 }
    34 int dis[maxn];
    35 int bs(int key,int n)
    36 {
    37     int left=1,right=n;
    38     while(left<=right)
    39     {
    40         int mid=(left+right)>>1;
    41         //printf("%d
    ",mid);
    42         if(dis[mid]>key)
    43             right=mid-1;
    44         else
    45             left=mid+1;
    46     }
    47     return left-1;
    48 }
    49 int main()
    50 {
    51     int n,m;
    52     while(scanf("%d%d",&n,&m)==2)
    53     {
    54         for(int i=1;i<=n;i++)
    55             scanf("%d%d",&f[i].l,&f[i].r);
    56         sort(f+1,f+n+1,cmp);
    57         init(n);
    58         dis[1]=0;
    59         for(int i=2;i<=idx;i++)
    60             dis[i]=g[i].l-g[i-1].r-1;
    61         for(int i=2;i<=idx;i++)
    62             dis[i]=dis[i-1]+dis[i];
    63     //    for(int i=1;i<=idx;i++)    printf("%d ",dis[i]);printf("
    ");
    64         int ans=0;
    65         for(int i=1;i<=idx;i++)
    66         {
    67             int x=bs(dis[i]+m,idx);
    68             int len=g[x].r-g[i].l+1+m-dis[x]+dis[i];
    69             if(len>ans)
    70                 ans=len;
    71         }
    72         printf("%d
    ",ans);
    73     }
    74     return 0;
    75 }

      

  • 相关阅读:
    如何进行数据库设计
    安装mysql后ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var mysql 启动不了
    Hive介绍、安装(转)
    Hadoop家族 路线图(转)
    Hive学习路线图(转)
    【CF949D】Curfew(贪心)
    【CF912E】Prime Game(meet in the middle)
    【BZOJ3872】Ant colony(二分,动态规划)
    【BZOJ2067】SZN(二分,动态规划,贪心)
    AtCoder Grand Contest 006
  • 原文地址:https://www.cnblogs.com/bitch1319453/p/7374337.html
Copyright © 2011-2022 走看看