比赛链接https://www.luogu.org/contest/show?tid=1084(md找不到超链接2333)
/*Dfs找最长半径(自己编的 不知道叫啥2333)*/ #include<cstdio> #define maxn 50010 using namespace std; int n,num,head[maxn],sum; struct node{ int v,t,pre; }e[maxn*2]; int init(){ int x=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} return x*f; } int max(int x,int y){ return x>y?x:y; } void Add(int from,int to,int dis){ num++;e[num].v=to; e[num].t=dis; e[num].pre=head[from]; head[from]=num; } int Dfs(int x,int from){ int r=0; for(int i=head[x];i;i=e[i].pre){ int v=e[i].v;if(v==from)continue; r=max(r,Dfs(v,x)+e[i].t); } return r; } int main() { n=init();int u,v,t; for(int i=1;i<n;i++){ u=init();v=init();t=init(); Add(u,v,t);Add(v,u,t);sum+=t; } printf("%d ",sum*2-Dfs(1,0)); return 0; }
/*找环+记忆化Dfs (自己yy的不是正解 但也挺快的)*/ #include<iostream> #include<cstdio> #define maxn 500010 #define ll long long using namespace std; int n,A[maxn],d[maxn],sum,belong[maxn],size[maxn]; int dfn[maxn],low[maxn],topt,f[maxn],s[maxn],top; ll ans,dp[maxn],len[maxn]; int init(){ int x=0;char s=getchar(); while(s<'0'||s>'9')s=getchar(); while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} return x; } void dfs(int x){ low[x]=dfn[x]=++topt; f[x]=1;s[++top]=x; int v=A[x]; if(dfn[v]==0){ dfs(v);low[x]=min(low[v],low[x]); } else if(f[v])low[x]=min(low[x],dfn[v]); if(low[x]==dfn[x]){ sum++; while(x!=s[top]){ len[sum]+=d[s[top]];f[s[top]]=0; belong[s[top]]=sum;top--;size[sum]++; } len[sum]+=d[s[top]];f[s[top]]=0; belong[s[top]]=sum;top--;size[sum]++; } } void Tarjan(){ for(int i=1;i<=n;i++) if(dfn[i]==0)dfs(i); for(int i=1;i<=n;i++) if(size[belong[i]]>1) dp[A[i]]=len[belong[i]]-d[i]; } ll Dfs(int x){ if(dp[x])return dp[x]; dp[x]=d[x]+Dfs(A[x]); return dp[x]; } int main() { n=init(); for(int i=1;i<=n;i++){ A[i]=init();d[i]=init(); } Tarjan(); for(int i=1;i<=n;i++) ans=max(ans,Dfs(i)); cout<<ans<<endl; return 0; }
/*研究好题目 nlon LIS*/ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 100010 using namespace std; int n,x,c[maxn],num; int init(){ int x=0;char s=getchar(); while(s<'0'||s>'9')s=getchar(); while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} return x; } int main() { n=init();c[0]=-0x7fffffff; for(int i=1;i<=n;i++) { x=init(); if(x>c[num]){c[++num]=x;continue;} int p=lower_bound(c+1,c+1+num,x)-c; c[p]=x; } printf("%d ",num); return 0; }
/* 之前做的时候n只有1000 这就比较好了 n*n暴力搞 今天比赛看到 我X 这么大的数据 丧心病狂啊直接 然后研究了std233333 nlogn的做法最大的两个点h才100 有套路 一片一片的搞 行列的h顺序无所谓 先排序 把一样高的挨起来搞 然后找一样高的 自己脑补一下图吧 (n,m)处的高度为H 然后向左下移动 一块小矩形都是H 体积可算 那剩下的矩形头顶和右边那一块也能确定高度 啦啦啦说不清楚啊 自己画图脑补一下吧23333 再来吐槽一下神数据 sort卡掉 merge卡掉 逼得我用桶排23333 */ #include<iostream> #include<cstdio> #include<cstring> #define maxn 5000001 #define ll long long using namespace std; int n,m,mxl[maxn],mxc[maxn],sl[maxn],sc[maxn],c[maxn],Tong1[1010],Tong2[1010]; ll mx,mi; int init(){ int x=0;char s=getchar(); while(s<'0'||s>'9')s=getchar(); while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} return x; } void Tong_sort(){ for(int i=0;i<=1000;i++) for(int j=1;j<=Tong1[i];j++) mxl[++n]=i; for(int i=0;i<=1000;i++) for(int j=1;j<=Tong2[i];j++) mxc[++m]=i; } int main() { n=init();m=init();int x; for(int i=1;i<=n;i++){ x=init();Tong1[x]++; } for(int i=1;i<=m;i++){ x=init();Tong2[x]++; } n=m=0; Tong_sort(); for(int i=1;i<=n;i++)sl[i]=sl[i-1]+mxl[i]; for(int i=1;i<=m;i++)sc[i]=sc[i-1]+mxc[i]; while(n||m){ int h=max(mxl[n],mxc[m]); int s1=0,s2=0; while(n&&mxl[n]==h)n--,s1++; while(m&&mxc[m]==h)m--,s2++; mx+=(ll)s1*s2*h+(ll)s1*sc[m]+(ll)s2*sl[n]; mi+=(ll)max(s1,s2)*h; } cout<<mi<<" "<<mx<<endl; return 0; }