zoukankan      html  css  js  c++  java
  • 多校 2013 8

    F

    给你ABC三个串 让你求D串

    D是AB的子序列 C是D的子串

    求D的长度

    求出C在AB中出现的位子记录开始位子和结束位子

    n^2 枚举在A中位子和在B中位子

    然后得到AB 开始位子之前的lcs 和AB结束位子的lcs

    开始预处理一下lcs

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <map>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include<set>
    #include<deque>
    #include<queue>
    #include<stack>
    
    using namespace std;
    
    #define inf 1000000007
    #define MAXN 1010
    #define ll long long
    
    char a[MAXN],b[MAXN],c[MAXN];
    int dp1[MAXN][MAXN],dp2[MAXN][MAXN];
    
    struct node
    {
        int ind1,ind2;
    }x1[MAXN],x2[MAXN];
    
    int main()
    {
    
        int t;
        scanf("%d",&t);
        int ca=1;
    
        while(t--)
        {
            scanf("%s%s%s",a+1,b+1,c+1);
            int len=strlen(c+1);
            int len1=strlen(a+1);
            int len2=strlen(b+1);
            memset(dp1,0,sizeof(dp1));
            memset(dp2,0,sizeof(dp2));
    
            for(int i=1;i<=len1;i++)
            {
                for(int j=1;j<=len2;j++)
                {
                    if(a[i]==b[j])
                        dp1[i][j]=dp1[i-1][j-1]+1;
                    else
                        dp1[i][j]=max(dp1[i-1][j],dp1[i][j-1]);
                }
            }
    
            for(int i=len1;i>=1;i--)
            {
                for(int j=len2;j>=1;j--)
                {
                    if(a[i]==b[j])
                        dp2[i][j]=dp2[i+1][j+1]+1;
                    else
                        dp2[i][j]=max(dp2[i+1][j],dp2[i][j+1]);
                }
            }
            int cnt1,cnt2;
            cnt1=cnt2=0;
    
            for(int i=1;i<=len1;i++)
            {
                if(a[i]==c[1])
                {
                    int k=2;
                    int j;
                    for(j=i+1;j<=len1&&k<=len;j++)
                    {
                        if(c[k]==a[j])
                        {
                             k++;
                        }
                    }
                    if(k==len+1)
                    {
                        x1[cnt1].ind1=i-1;
                        x1[cnt1].ind2=j;
                        cnt1++;
                    }
                }
            }
    
             for(int i=1;i<=len2;i++)
            {
                if(b[i]==c[1])
                {
                    int k=2;
                    int j;
                    for(j=i+1;j<=len2&&k<=len;j++)
                    {
                        if(c[k]==b[j])
                        {
                             k++;
                        }
                    }
                    if(k==len+1)
                    {
                        x2[cnt2].ind1=i-1;
                        x2[cnt2].ind2=j;
                        cnt2++;
                    }
                }
            }
            int mx=0;
    
            for(int i=0;i<cnt1;i++)
            {
                for(int j=0;j<cnt2;j++)
                {
                    mx=max(mx,dp1[x1[i].ind1][x2[j].ind1]+dp2[x1[i].ind2][x2[j].ind2]+len);
                }
            }
            printf("Case #%d: %d
    ",ca++,mx);
        }
        return 0;
    }
    View Code

     D

    n个点n-1条边 你只可以去掉一条 花费是 这条边的权  * (块里面最大的距离)   要求这个最小

    显然这个和树的直径有关 那么先2遍dfs求树的直径

    然后枚举每条边   1  这条边在直径上 那么要求的就是边两端点对应的子树的最大深度

                                2 不在直径上 那么就是边权*直径

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    
    using namespace std;
    
    #define inf 2e9+7
    #define MAXN 100010
    int head[MAXN];
    struct node
    {
        int v,w,next,id;
    }edge[MAXN<<1];
    int ds[MAXN],dt[MAXN],cnt,ms[MAXN],mt[MAXN];
    
    void add(int u,int v,int w,int id)
    {
        edge[cnt].id=id;
        edge[cnt].v=v;
        edge[cnt].w=w;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    
    void dfs(int u,int fa)
    {
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            if(v==fa)
                continue;
            ds[v]=ds[u]+1;
            dfs(v,u);
        }
    }
    void dfs1(int u,int fa)
    {
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            if(v==fa)
                continue;
            dt[v]=dt[u]+1;
            dfs1(v,u);
        }
    }
    void dfs2(int u,int fa)
    {
        mt[u]=dt[u];
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            if(v==fa)
                continue;
            dfs2(v,u);
            mt[u]=max(mt[u],mt[v]);
        }
    }
    void dfs3(int u,int fa)
    {
        ms[u]=ds[u];
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            if(v==fa)
                continue;
            dfs3(v,u);
            ms[u]=max(ms[u],ms[v]);
        }
    }
    
    int id,ans,len;
    
    void dfs4(int u,int fa)
    {
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            if(v==fa)
                continue;
            if(ds[u]+dt[v]+1==len)
            {
                if(max(ms[u],mt[v])*edge[i].w<ans)
                {
                    ans=max(ms[u],mt[v])*edge[i].w;
                    id=edge[i].id;
                }
                else if(max(ms[u],mt[v])*edge[i].w==ans&&edge[i].id<id)
                    id=edge[i].id;
            }
            else
            {
                 if(len*edge[i].w<ans)
                {
                    ans=len*edge[i].w;
                    id=edge[i].id;
                }
                else if(len*edge[i].w==ans&&edge[i].id<id)
                    id=edge[i].id;
            }
            dfs4(v,u);
        }
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        int ca=1;
    
        while(t--)
        {
            int n;
            scanf("%d",&n);
            cnt=0;
            memset(head,-1,sizeof(head));
            for(int i=1;i<n;i++)
            {
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                add(u,v,w,i);
                add(v,u,w,i);
            }
            ds[1]=0;
            dfs(1,-1);
            int s=1;
            for(int i=1;i<=n;i++)
                if(ds[i]>ds[s])
                    s=i;
            ds[s]=0;
            dfs(s,-1);
            int tt=1;
            len=ds[1];
            for(int i=1;i<=n;i++)
                if(ds[i]>ds[tt])
                 {
                      tt=i;
                      len=ds[i];
                 }
            dt[tt]=0;
            dfs1(tt,-1);
            dfs2(s,-1);
            dfs3(tt,-1);
            ans=inf;
            dfs4(s,-1);
            printf("Case #%d: %d
    ",ca++,id);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    【转载】opencvVS2019配置方法
    windows.h头文件中改变光标位置的函数——SetConsoleCursorPosition
    五行代码解决猴子选大王问题
    AtCoder Beginner Contest 192
    ACM做题注意事项
    数据库部分重点
    数据库7-11章期末复习
    数据库4-6章期末复习
    数据库1-3章期末复习
    ICPC Central Russia Regional Contest (CRRC 19)
  • 原文地址:https://www.cnblogs.com/cherryMJY/p/7258702.html
Copyright © 2011-2022 走看看