标签:lower tran long strong 1.0 fine 模拟 hit 级别
emmm...作为本蒟蒻的实际意义上的第一篇博客,当然要认真写写才不反正也没什么人看
T1 题意简述:求二元不定方程的正整数解组数。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
ll n,blk,cnt,head[2001],siz[2001],dp[2001][2001];
struct uio{
    ll nxt,to,val;
}edge[4001];
void add(ll x,ll y,ll z)
{
    edge[++cnt].nxt=head[x];
    edge[cnt].to=y;
    edge[cnt].val=z;
    head[x]=cnt;
}
void dfs(ll x,ll fa)
{
    siz[x]=1;
    dp[x][0]=dp[x][1]=0;
    for(ll i=head[x];i;i=edge[i].nxt)
    {
        ll y=edge[i].to;
        if(y==fa) continue;
        dfs(y,x);
        siz[x]+=siz[y];
    }
    for(ll i=head[x];i;i=edge[i].nxt)
    {
        ll y=edge[i].to,z=edge[i].val;
        if(y==fa) continue;
        for(ll j=min(siz[x],blk);j>=0;j--)
            for(ll k=0;k<=min(j,siz[y]);k++)
                if(dp[x][j-k]!=-1)
                {
                    ll wei=z*(k/*此子树黑点个数*/*(blk-k)/*另一子树黑点个数*/+
                            (siz[y]-k)/*此子树白点个数*/*(n-blk-(siz[y]-k))/*另一子树白点个数*/);
                    dp[x][j]=max(dp[x][j],dp[x][j-k]+dp[y][k]+wei);
                }
    }
}
int main()
{
    freopen("coloration.in","r",stdin);
    freopen("coloration.out","w",stdout);
    scanf("%lld%lld",&n,&blk);
    for(ll i=1;i<n;i++)
    {
        ll u,v,w;
        scanf("%lld%lld%lld",&u,&v,&w);
        add(u,v,w),add(v,u,w);
    }
    memset(dp,-1,sizeof(dp));
    dfs(1,0);
    printf("%lld\n",dp[1][blk]);
    return 0;
}

n,m,k≤100000
解题思路:首先感谢坐在我旁边的erkkierkko大佬教会我这道题。erkkierkko大佬TQL!!!
容易看出,光线改变方向的次数是O(n+m+k)级别的,因此我们可以进行模拟。
把障碍存在set里(边界也要存),每次由光线所在位置及朝向方向+lower_bound即可得出下一障碍位置。
时间复杂度O((n+m+k)logn )。
由于光线必然不会相交 <=== erkkierkko大佬证明得出
             因此不必去重,且结束条件仅两种:
1.光线回到起点,且路径上的每个点都只经过一次
2.光线回到起点,且路径上的每个点都经过了两次
对于这两种情况,只需记录是否曾沿反方向经过了起点,若是则将ans/2,否则直接输出ans即可。
代码:尚未码出,稍后补足。(咕咕咕?)
标签:lower tran long strong 1.0 fine 模拟 hit 级别
原文地址:https://www.cnblogs.com/water-radish/p/9315121.html