8.13模拟赛

T1 HOTEL 

题目大意:

在树上选出三个点使这三个两两之间距离相等 求选出这三个点的方案

思路:

树形dp

枚举每一个树根 选三个和选两个差不多 多开一个dp数组

 1 #include<iostream>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<queue>
 8 #include<vector>
 9 #include<set>
10 #define MAXN 5010
11 #define ll long long
12 #define inf 2139062143
13 using namespace std;
14 inline int read()
15 {
16     int x=0,f=1;char ch=getchar();
17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
19     return x*f;
20 }
21 int n,fst[MAXN],to[MAXN<<1],nxt[MAXN<<1],cnt,dep[MAXN];
22 ll tmp[MAXN],dp[MAXN][2],ans;
23 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
24 void dfs(int x,int fa)
25 {
26     tmp[dep[x]]++;
27     for(int i=fst[x];i;i=nxt[i])
28         if(to[i]!=fa) {dep[to[i]]=dep[x]+1;dfs(to[i],x);}
29 }
30 int main()
31 {
32     n=read();int a,b;
33     for(int i=1;i<n;i++){a=read(),b=read();add(a,b);add(b,a);}
34     for(int x=1;x<=n;x++)
35     {
36         memset(dp,0,sizeof(dp));
37         for(int i=fst[x];i;i=nxt[i])
38         {
39             dep[to[i]]=1;dfs(to[i],x);
40             for(int j=1;j<=n;j++)
41                 ans+=dp[j][0]*tmp[j],dp[j][0]+=dp[j][1]*tmp[j],dp[j][1]+=tmp[j];
42             memset(tmp,0,sizeof(tmp));
43         }
44     }
45     printf("%lld",ans);
46 }
View Code

 

T2 Chips Challenge

题目大意:

有一个芯片,芯片上有N*N(1≤N≤40)个插槽,可以在里面装零件。

有些插槽不能装零件,有些插槽必须装零件,剩下的插槽随意。

要求装好之后满足如下两条要求:

1、第 i 行和第 i 列的零件数目必须一样多(1≤i≤N)。

2、第 i 行的零件数目不能超过总的零件数目的 A/B(1≤i≤N,0≤A≤B≤1000,B≠0)。

求最多可以另外放多少个零件 如果无解输出impossible

思路:

 

 

T3 Mst

题目大意:

给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树

思路:

先搞出最小生成树

如果删的边不是树边 不影响

如果是即我们需要一条非树边将这两个联通块联通,可以将所有非树边按照从大至小的顺序,将这个边的两个端点在树上的路径的答案修改为该边的权值

每次询问的时候查询这条边的答案

  1 #include<iostream>
  2 #include<cmath>
  3 #include<algorithm>
  4 #include<cstdio>
  5 #include<cstring>
  6 #include<cstdlib>
  7 #include<queue>
  8 #include<vector>
  9 #include<set>
 10 #define MAXN 50100
 11 #define ll long long
 12 #define inf 2139062143
 13 using namespace std;
 14 inline int read()
 15 {
 16     int x=0,f=1;char ch=getchar();
 17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
 18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
 19     return x*f;
 20 }
 21 int n,m,fst[MAXN],nxt[MAXN<<1],to[MAXN<<1],cnt,etr[MAXN<<1],hvs[MAXN];
 22 int fa[MAXN],trs[MAXN<<1],hsh[MAXN],sz[MAXN],dep[MAXN],bl[MAXN],ans,f;
 23 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
 24 struct edge{int u,v,val,id;}e[MAXN<<1];
 25 bool cmp(edge a,edge b) {return a.val<b.val;}
 26 int find(int x) {return x==fa[x]?x:fa[x]=find(fa[x]);}
 27 bool ok(int a,int b)
 28 {
 29     int f1=find(a),f2=find(b);
 30     if(f1!=f2) {fa[f1]=f2;return 0;}
 31     return 1;
 32 }
 33 void kruskal(int res)
 34 {
 35     sort(e+1,e+m+1,cmp);
 36     for(int i=1;i<=m;i++)
 37         if(!ok(e[i].u,e[i].v)) {res++,ans+=e[i].val;add(e[i].u,e[i].v);add(e[i].v,e[i].u);trs[e[i].id]=i,etr[i]=1;}
 38     if(res!=n-1) f=1;
 39 }
 40 void dfs(int x)
 41 {
 42     sz[x]=1,dep[x]=dep[fa[x]]+1;
 43     for(int i=fst[x];i;i=nxt[i])
 44         if(to[i]!=fa[x]) {fa[to[i]]=x;dfs(to[i]);sz[x]+=sz[to[i]];}
 45 }
 46 void Dfs(int x,int anc)
 47 {
 48     hsh[x]=++cnt,bl[x]=anc;
 49     for(int i=fst[x];i;i=nxt[i])
 50         if(dep[to[i]]>dep[x]&&sz[hvs[x]]<sz[to[i]]) hvs[x]=to[i];
 51     if(!hvs[x]) {hvs[x]=x;return ;}Dfs(hvs[x],anc);
 52     for(int i=fst[x];i;i=nxt[i])
 53         if(dep[to[i]]>dep[x]&&to[i]!=hvs[x]) {Dfs(to[i],to[i]);}
 54 }
 55 int mn[MAXN<<2],tag[MAXN<<2];
 56 void pshd(int k,int l,int r,int mid)
 57 {
 58     tag[k<<1]=tag[k<<1|1]=tag[k];
 59     mn[k<<1]=tag[k],mn[k<<1|1]=tag[k],tag[k]=0;
 60 }
 61 void mdf(int k,int l,int r,int a,int b,int x)
 62 {
 63     if(l==a&&r==b) {mn[k]=tag[k]=x;return ;}
 64     int mid=(l+r)>>1;
 65     if(tag[k]) pshd(k,l,r,mid);
 66     if(mid>=b) mdf(k<<1,l,mid,a,b,x);
 67     else if(mid<a) mdf(k<<1|1,mid+1,r,a,b,x);
 68     else {mdf(k<<1,l,mid,a,mid,x);mdf(k<<1|1,mid+1,r,mid+1,b,x);}
 69     mn[k]=min(mn[k<<1],mn[k<<1|1]);
 70 }
 71 int query(int k,int l,int r,int x)
 72 {
 73     if(l==r) return mn[k];
 74     int mid=(l+r)>>1;
 75     if(tag[k]) pshd(k,l,r,mid);
 76     if(mid>=x) return query(k<<1,l,mid,x);
 77     else query(k<<1|1,mid+1,r,x);
 78 }
 79 void tr_mdf(int a,int b,int x)
 80 {
 81     while(bl[a]!=bl[b])
 82     {
 83         if(dep[bl[a]]<dep[bl[b]]) swap(a,b);
 84         mdf(1,1,n,hsh[bl[a]],hsh[a],x);
 85         a=fa[bl[a]];
 86     }
 87     if(dep[a]<dep[b]) swap(a,b);
 88     if(a!=b) mdf(1,1,n,hsh[hvs[b]],hsh[a],x);
 89 }
 90 int main()
 91 {
 92     n=read(),m=read();
 93     for(int i=1;i<=n;i++) fa[i]=i;
 94     for(int i=1;i<=m;i++) e[i].id=i,e[i].u=read(),e[i].v=read(),e[i].val=read();
 95     kruskal(0);fa[1]=1;dfs(1);cnt=0;Dfs(1,1);int T=read(),x;
 96     if(!f) for(int i=m;i;i--) if(!etr[i]) tr_mdf(e[i].u,e[i].v,e[i].val);
 97     while(T--)
 98     {
 99         x=trs[read()];
100         if(f) {puts("Not connected");continue;}
101         if(etr[x])
102         {
103             if(query(1,1,n,max(hsh[e[x].u],hsh[e[x].v]))) printf("%d\n",ans-e[x].val+query(1,1,n,max(hsh[e[x].u],hsh[e[x].v])));
104             else puts("Not connected");
105         }
106         else printf("%d\n",ans);
107     }
108 }
View Code
posted @ 2018-08-13 15:29  jack_yyc  阅读(177)  评论(0编辑  收藏  举报