1. 程式人生 > >多校 2013 8

多校 2013 8

stdio.h b- strlen next 端點 gif tdi open long

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\n",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\n",ca++,id);
    }
    return 0;
}
View Code

多校 2013 8