2014 Multi-University Training Contest 1

官方解题报告http://blog.sina.com.cn/s/blog_a19ad7a10102uyes.html

A.2014 <wbr>Multi-University <wbr>Training <wbr>Contest <wbr>1--by <wbr>FZU <wbr>解题报告

B. Jump

最小K路径覆盖的模型,用费用流或者KM算法解决,构造二部图,X部有N*M个节点,源点向X部每个节点连一条边,流量1,费用0Y部有N*M个节点,每个节点向汇点连一条边,流量1,费用0,如果X部的节点x可以在一步之内到达Y部的节点y,那么就连边x->y,费用为从x格子到y格子的花费能量减去得到的能量,流量1,再在X部增加一个新的节点,表示可以从任意节点出发K次,源点向其连边,费用0,流量K,这个点向Y部每个点连边,费用0,流量1,最这个图跑最小费用最大流,如果满流就是存在解,反之不存在,最小费用的相反数就是可以获得的最大能量

C. Centroid of a Tree

首先找出重心,之后以重心为根进行树形dp,用dp[i][j]表示以编号为i的节点为根的子树有j个儿子的方案数 ,这个直接合并,每次合并两个子树的时候枚举两个子树的儿子的个数,对于树上每条边合并一次,总共合并次,每次合并的复杂度是n^2,这个是三方的复杂度。

对于有两个重心的情况,首先将这两个子树中间的边打断变成两个树,对这两个树分别按照上述方法处理出dp 数组,如果要使得重心位置不变,那么这两个子树需要有相同的节点个数,这个直接枚举一下然后两边乘起来 就好了。

至于只有一个重心的情况,还是按照上述方法处理出dp数组,为了计算合法的方案数,我们用总的方案数减去 不合法的方案数,对于不合法的情况,去掉这个根后一定会有一个最大的分支,这个分支的节点数超过剩下的 全部分支加起来的节点个数,所以先枚举最大分支,对于剩下的分支用背包处理,f[i]表示剩下的全部子树取个节点的方案数,这个很容易处理,处理完之后枚举一下最大分支的节点个数,再利用f数组就可以算出在这种 情况下的非法的方案数了。

对于这里的复杂度要特别说明一下,设每个分支的节点数是x1,x2,x3...,xk,合并的复杂度是x1*x2+(x1+x2) *x3+...+(x1+x2+...+xk-1)*xk<=(x1+x2+...+xk)^2=n^2,加上枚举是三方,所以整个dp的总复杂度是三方的。

D. Task

基本思想是贪心。

对于价值c=500*xi+2*yiyi最大影响100*2<500,所以就是求xi总和最大。可以先对机器和任务的时间从大到小排序。从最大时间的任务开始,找出满足任务时间要求的所有机器,从中找出等级最低且满足任务等级要求的机器匹配。依次对任务寻找满足要求的机器。

2014 <wbr>Multi-University <wbr>Training <wbr>Contest <wbr>1--by <wbr>FZU <wbr>解题报告

F. Shooting

将所有目标与起点线的距离离散化作为下标,建立函数式线段树,将距离按区间端点从1X的顺序加入函数式线段树,左端点+1,右端点-1,记录区间元素的距离和,以及元素的个数。对于在x位置的询问,找到其对应的端点,这个可以二分找到,然后在该端点对应的线段树上进行二分查找求解,最后判断前一个答案与P的大小得到当前问题的答案。

G. Xor

线段树,时间复杂度是O5000*200*logn+10*m*logn)。

f[ prefix ]保存2进制前缀状态,合并就暴力,比如

101xxx

11xxxx

x表示0或者1
前缀固定 后面随便取
这2个xor的结果
只有前2位是确定的 

合并完大约就是

01xxxx

然后方案数就可以算了,可以证明,状态不会太多。

H. Information Extraction

本题要求大家能够存储特定的输出格式以及若干种HTML结构和映射关系,根据输入的HTML文本,寻找其结构,如果找不到结构与之匹配,输出“Can't Identify”,如果只有一个,根据映射关系以及输出格式的要求输出结果,如果有多个,则使用最早输入的那个结构。

解决以下几点即可

1、对HTML输入的读取

2、判断结构是不是输入的HTML文本的结构

3、根据映射以及输出格式的要求输出结果

注意映射关系中可能有一个id到多个标签,并且这些标签在输入格式中是存在多个的。

I. Turn the pokers

最终的结果一定是连续出现的,只需要求出最终的区间。

因为如果对同一张牌进行两次操作,牌的状态不改变。故牌的翻转次数一定是减少偶数次。如果所有数的和是奇数,那么最终结果也一定是奇数。同理,偶数也是一样的。

所以只要递推求出最后的区间,计算sumCxim)(i=012。。。)),m是总牌数,xi是在区间内连续的奇数或偶数,在模10^9+9就是最终的答案。

J. Rating

(x, y)表示高分为x,低分为y的状态(x >= y),E(x, y)表示从(x, y)到达(1000, ?)的比赛场数期望。容易得到E(x, y) = P * E(x1, y1) + (1 - P) * E(x2, y2) + 1,其中,(x1, y1)表示rating上升后的状态,(x2, y2)表示rating下降后的状态。把E(1000, ?) = 0带入可以得到包含n个未知数的n个方程,n大概200多,可以高斯消元。E(0, 0)即为答案。

K. Shortest-path tree

首先构造最短路径树。先求根节点到其他节点的最短路径,然后从根节点开始进行深度优先遍历,先遍历节点编号较小的没遍历过的儿子,这样就能处理处最短路径树。

之后找节点数为K的树链。可以用树分治进行求解,在树分治求解过程中,对于每个中心点,处理出该子树中所有节点到中心点的树链,然后枚举每条树链,比如某条树链节点为a,长度为b,则找之前遍历过的树链中节点数位K-a的长度最长的树链,将这两条树链拼起来可以得到节点数为K的树链,用其更新答案。最好一个一个分支分别处理,可以避免考虑同一个分支来的两条树链。这样枚举并且更新信息,还要存方案数。

Couple doubi http://acm.hdu.edu.cn/showproblem.php?pid=4861

找规律。

 1 #include<cstdio>
 2 using namespace std;
 3 int main(){
 4     int n,p;
 5     while(~scanf("%d%d",&n,&p)){
 6         if(n/(p-1)&1)puts("YES");
 7         else puts("NO");
 8     }
 9     return 0;
10 }
View Code

Jump http://acm.hdu.edu.cn/showproblem.php?pid=4862

最小费用最大流。id[][]给每个点标号表示左侧,id[][]+cnt表示右侧点,源点s连每一个左侧点,每一个右侧点连到汇点en。流量都是1,费用都是0。在一个中间点ps,源点s到他k的流,ps到每一个右侧点1的流,因为走k次,这里也就相当于这个点不经过其他点,直接流向en,但只有k个起点。题目要求赚最大能量,把能量取个相反数,当做费用,这样求的最小费用的绝对值就是最大能量了。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #define mt(a,b) memset(a,b,sizeof(a))
  5 using namespace std;
  6 const int M=1010;
  7 const int inf = 0x3f3f3f3f;
  8 class MaxflowMincost { //最小费用最大流
  9     struct E {
 10         int u,v,next,flow,cost;
 11     } e[M<<4];
 12     queue<int> q;
 13     int le,flow,cost,head[M],cur[M],dis[M],pre[M];
 14     bool used[M],sign[M];
 15 public:
 16     int getcost() {
 17         return cost;
 18     }
 19     int getflow() {
 20         return flow;
 21     }
 22     bool spfa(int s,int t) {
 23         mt(used,0);
 24         mt(sign,0);
 25         mt(dis,0);
 26         while(!q.empty()) q.pop();
 27         q.push(s);
 28         used[s]=sign[s]=true;
 29         while(!q.empty()) {
 30             int u=q.front();
 31             q.pop();
 32             used[u]=false;
 33             for(int i=head[u]; ~i; i=e[i].next) {
 34                 if(e[i].flow<1) continue;
 35                 int v=e[i].v;
 36                 if(!sign[v]||dis[v]>dis[u]+e[i].cost) {
 37                     dis[v]=dis[u]+e[i].cost;
 38                     sign[v]=true;
 39                     pre[v]=u;
 40                     cur[v]=i;
 41                     if(used[v]) continue;
 42                     used[v]=true;
 43                     q.push(v);
 44                 }
 45             }
 46         }
 47         return sign[t];
 48     }
 49     void init() {
 50         le=0;
 51         mt(head,-1);
 52     }
 53     void add(int u,int v,int flow,int cost) {
 54         e[le].u=u;
 55         e[le].v=v;
 56         e[le].flow=flow;
 57         e[le].cost=cost;
 58         e[le].next=head[u];
 59         head[u]=le++;
 60         e[le].u=v;
 61         e[le].v=u;
 62         e[le].flow=0;
 63         e[le].cost=-cost;
 64         e[le].next=head[v];
 65         head[v]=le++;
 66     }
 67     void solve(int s,int t) {
 68         flow=cost=0;
 69         while(spfa(s,t)) {
 70             int temp=t;
 71             int now=inf;
 72             while(temp!=s) {
 73                 now=min(now,e[cur[temp]].flow);
 74                 temp=pre[temp];
 75             }
 76             flow+=now;
 77             temp=t;
 78             while(temp!=s) {
 79                 cost+=now*e[cur[temp]].cost;
 80                 e[cur[temp]].flow-=now;
 81                 e[cur[temp]^1].flow+=now;
 82                 temp=pre[temp];
 83             }
 84         }
 85     }
 86 } gx;
 87 char str[16][16];
 88 int id[16][16];
 89 int main() {
 90     int T,n,m,k;
 91     while(~scanf("%d",&T)) {
 92         int cas=1;
 93         while(T--) {
 94             scanf("%d%d%d",&n,&m,&k);
 95             for(int i = 0; i < n; i++)
 96                 scanf("%s",str[i]);
 97             printf("Case %d : ",cas++);
 98             gx.init();
 99             int cnt=0;
100             for(int i=0;i<n;i++){
101                 for(int j=0;j<m;j++){
102                     id[i][j]=cnt++;
103                 }
104             }
105             int st=cnt++;
106             int ps=cnt++;
107             int en=cnt++;
108             gx.add(st,ps,k,0);
109             for(int i = 0; i < n; i++){
110                 for(int j = 0,w; j < m; j++) {
111                     gx.add(st,id[i][j],1,0);
112                     gx.add(id[i][j]+cnt,en,1,0);
113                     gx.add(ps,id[i][j]+cnt,1,0);
114                     for(int y = j+1; y < m; y++) {
115                         w=y-j-1;
116                         if(str[i][y] == str[i][j])
117                             w-=str[i][j]-'0';
118                         gx.add(id[i][j],id[i][y]+cnt,1,w);
119                     }
120                     for(int x = i+1; x < n; x++) {
121                         w=x-i-1;
122                         if(str[x][j] == str[i][j])
123                             w-=str[i][j]-'0';
124                         gx.add(id[i][j],id[x][j]+cnt,1,w);
125                     }
126                 }
127             }
128             gx.solve(st,en);
129             int flow=gx.getflow();
130             int cost=gx.getcost();
131             if(flow != n*m)printf("-1
");
132             else printf("%d
",-cost);
133         }
134     }
135     return 0;
136 }
View Code

Centroid of a Tree http://acm.hdu.edu.cn/showproblem.php?pid=4863

dfs是树形dp找重心,然后看看有几个重心,不是一个就是两个,分两种情况讨论,如果是两个重心,将重心之间的边断开,两边分别DFS处理出dp[i][j]表示i号节点为根的子树有j个儿子的方案数。这里还没全懂。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<vector>
  4 #include<algorithm>
  5 #define mt(a,b) memset(a,b,sizeof(a))
  6 using namespace std;
  7 const int M=512;
  8 const int mod=10007;
  9 struct G {
 10     struct E {
 11         int u,v,next;
 12         bool flag;
 13     } e[M*M];
 14     int le,head[M];
 15     void init() {
 16         le=0;
 17         mt(head,-1);
 18     }
 19     void add(int u,int v) {
 20         e[le].u=u;
 21         e[le].v=v;
 22         e[le].flag=true;
 23         e[le].next=head[u];
 24         head[u]=le++;
 25     }
 26 } g;
 27 int n,num[M],big[M];
 28 void dfs(int u,int fa) { //find center
 29     num[u]=1;
 30     big[u]=0;
 31     for(int i=g.head[u]; ~i; i=g.e[i].next) {
 32         int v=g.e[i].v;
 33         if(v!=fa) {
 34             dfs(v,u);
 35             num[u]+=num[v];
 36             big[u]=max(big[u],num[v]);
 37         }
 38     }
 39     big[u]=max(big[u],n-num[u]);
 40 }
 41 struct S{
 42     int id,val;
 43     friend bool operator <(S a,S b){
 44         return a.val<b.val;
 45     }
 46 }b[M];
 47 int dp[M][M];//dp[i][j]表示以编号为i的节点为根的子树有j个儿子的方案数
 48 int save[M];
 49 void DFS(int u,int fa) {
 50     for(int i=0; i<=n; i++) dp[u][i]=0;
 51     dp[u][0]=1;
 52     int T=0;
 53     for(int i=g.head[u]; ~i; i=g.e[i].next) {
 54         if(g.e[i].flag) {
 55             int v=g.e[i].v;
 56             if(v!=fa) {
 57                 DFS(v,u);
 58                 for(int j=0; j<=n; j++) save[j]=0;
 59                 for(int a=0; a<=T; a++)
 60                     for(int b=0; b<=num[v]; b++) {
 61                         int add=(dp[u][a]*dp[v][b])%mod;
 62                         save[a+b]=(save[a+b]+add)%mod;
 63                     }
 64                 for(int a=0; a<=n; a++)
 65                     dp[u][a]=save[a];
 66                 T+=num[v];
 67             }
 68         }
 69     }
 70     for(int i=n; i>=0; i--)
 71         dp[u][i+1]=dp[u][i];
 72     dp[u][0]=1;
 73 }
 74 int f[2][M];
 75 int main() {
 76     int t,x,y;
 77     while(~scanf("%d",&t)) {
 78         int cas=1;
 79         while(t--) {
 80             scanf("%d",&n);
 81             g.init();
 82             for(int i=0;i<n-1;i++) {
 83                 scanf("%d%d",&x,&y);
 84                 g.add(x,y);
 85                 g.add(y,x);
 86             }
 87             printf("Case %d: ",cas++);
 88             dfs(1,-1);
 89             int lb=0;
 90             for(int i=1;i<=n;i++){
 91                 b[lb].id=i;
 92                 b[lb].val=big[i];
 93                 lb++;
 94             }
 95             sort(b,b+lb);
 96             if((lb>1&&b[0].val<b[1].val)||lb==1){  //一个重心
 97                 int rt=b[0].id;
 98                 dfs(rt,-1);
 99                 DFS(rt,-1);
100                 int ans=1;
101                 for(int i=g.head[rt]; ~i; i=g.e[i].next) {
102                     int v=g.e[i].v;
103                     int T=0;
104                     for(int j=0; j<=n; j++)
105                         T=(T+dp[v][j])%mod;
106                     ans=(ans*T)%mod;
107                 }
108                 for(int i=g.head[rt]; ~i; i=g.e[i].next) {
109                     int x=g.e[i].v;
110                     int T=0;
111                     int now=0;
112                     int pre=1;
113                     memset(f,0,sizeof(f));
114                     f[now][0]=1;
115                     for(int j=g.head[rt];~j;j=g.e[j].next){
116                         if(i == j) continue;
117                         int y=g.e[j].v;
118                         now^=1;
119                         pre^=1;
120                         for(int a=0; a<=n; a++)
121                             f[now][a]=0;
122                         for(int a=0; a<=T; a++)
123                             for(int b=0; b<=num[y]; b++) {
124                                 f[now][a+b]+=f[pre][a]*dp[y][b];
125                                 f[now][a+b]%=mod;
126                             }
127                         T+=num[y];
128                     }
129                     int sum=0;
130                     for(int j=1; j<=n; j++) {
131                         sum=(sum+f[now][j-1])%mod;
132                         int add=(dp[x][j]*sum)%mod;
133                         ans=(ans-add+mod)%mod;
134                     }
135                 }
136                 printf("%d
",ans);
137             } else {  //two center
138                 int x=b[0].id;
139                 int y=b[1].id;
140                 for(int i=0;i<g.le;i++){
141                     if((g.e[i].u==x&&g.e[i].v==y)||(g.e[i].u==y&&g.e[i].v==x)){
142                         g.e[i].flag=false;
143                         g.e[i^1].flag=false;
144                         break;
145                     }
146                 }
147                 DFS(x,-1);
148                 DFS(y,-1);
149                 int ans=0;
150                 for(int i=1; i<=n; i++) {
151                     int add=(dp[x][i]*dp[y][i])%mod;
152                     ans=(ans+add)%mod;
153                 }
154                 printf("%d
",ans);
155             }
156         }
157     }
158     return 0;
159 }
View Code

Task http://acm.hdu.edu.cn/showproblem.php?pid=4864

二级排序,然后对x单调队列,y标记然后暴力找最接近的一个。y是100,所以复杂度o(m*100)。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<cctype>
 6 #include<iostream>
 7 #include<algorithm>
 8 #include<queue>
 9 #define mt(a,b) memset(a,b,sizeof(a))
10 using namespace std;
11 typedef __int64 LL;
12 const int M=100010;
13 struct NODE{
14     int x,y;
15     friend bool operator <(NODE a,NODE b){
16         if(a.x==b.x) return a.y>b.y;
17         return a.x>b.x;
18     }
19 }mach[M],task[M];
20 int ma[128];
21 int main(){
22     int n,m;
23     while(~scanf("%d%d",&n,&m)){
24         mt(ma,0);
25         for(int i=0;i<n;i++){
26             scanf("%d%d",&mach[i].x,&mach[i].y);
27         }
28         for(int i=0;i<m;i++){
29             scanf("%d%d",&task[i].x,&task[i].y);
30         }
31         sort(mach,mach+n);
32         sort(task,task+m);
33         int ans=0;
34         LL sum=0;
35         int id=0;
36         for(int i=0;i<m;i++){
37             while(mach[id].x>=task[i].x&&id<n){
38                 ma[mach[id].y]++;
39                 id++;
40             }
41             for(int j=task[i].y;j<=100;j++){
42                 if(ma[j]){
43                     ma[j]--;
44                     ans++;
45                     sum+=500*task[i].x+2*task[i].y;
46                     break;
47                 }
48             }
49         }
50         printf("%d %I64d
",ans,sum);
51     }
52     return 0;
53 }
View Code

Peter's Hobby http://acm.hdu.edu.cn/showproblem.php?pid=4865

dp求一个概率最大的序列,记录路径,类似上海邀请赛c。

 1 #include<cstdio>
 2 #include<cstring>
 3 #define mt(a,b) memset(a,b,sizeof(a))
 4 const int M=64;
 5 char yezi[4][8]={"Dry","Dryish","Damp","Soggy"};
 6 char tian[3][8]={"Sunny","Cloudy","Rainy"};
 7 int a[M];
 8 char op[8];
 9 double dp[M][3];
10 int pre[M][3];
11 int ans[M];
12 double f[3][4]={
13     0.60,0.20,0.15,0.05,
14     0.25,0.30,0.20,0.25,
15     0.05,0.10,0.35,0.50,
16 };
17 double s[3][3]={
18     0.500,0.375,0.125,
19     0.250,0.125,0.625,
20     0.250,0.375,0.375,
21 };
22 int main(){
23     int t,n;
24     while(~scanf("%d",&t)){
25         int cas=1;
26         while(t--){
27             scanf("%d",&n);
28             for(int i=1;i<=n;i++){
29                 scanf("%s",op);
30                 for(int j=0;j<4;j++){
31                     if(!strcmp(op,yezi[j])){
32                         a[i]=j;
33                         break;
34                     }
35                 }
36             }
37             mt(dp,0);
38             mt(pre,-1);
39             dp[1][0]=0.63*f[0][a[1]];
40             dp[1][1]=0.17*f[1][a[1]];
41             dp[1][2]=0.20*f[2][a[1]];
42             for(int i=2;i<=n;i++){
43                 for(int j=0;j<3;j++){
44                     for(int k=0;k<3;k++){
45                         if(dp[i][j]<dp[i-1][k]*s[k][j]*f[j][a[i]]){
46                             dp[i][j]=dp[i-1][k]*s[k][j]*f[j][a[i]];
47                             pre[i][j]=k;
48                         }
49                     }
50                 }
51             }
52             double big=0;
53             int id;
54             for(int i=0;i<3;i++){
55                 if(big<dp[n][i]){
56                     big=dp[n][i];
57                     id=i;
58                 }
59             }
60             int la=0;
61             int x=n;
62             ans[la++]=id;
63             while(pre[x][id]!=-1){
64                 id=pre[x][id];
65                 ans[la++]=id;
66                 x--;
67             }
68             printf("Case #%d:
",cas++);
69             for(int i=la-1;i>=0;i--){
70                 puts(tian[ans[i]]);
71             }
72         }
73     }
74     return 0;
75 }
View Code

Shooting http://acm.hdu.edu.cn/showproblem.php?pid=4866

主席树,待补。

  1 #include<cstdio>
  2 #include<algorithm>
  3 using namespace std;
  4 const int MAXN = 200010;
  5 const int M = MAXN * 100;
  6 int n,tot;
  7 int T[MAXN];
  8 int lson[M],rson[M];
  9 int c1[M];
 10 long long c2[M];
 11 int build(int l,int r) {
 12     int root = tot++;
 13     c1[root] = 0;
 14     c2[root] = 0;
 15     if(l != r) {
 16         int mid = (l+r)/2;
 17         lson[root] = build(l,mid);
 18         rson[root] = build(mid+1,r);
 19     }
 20     return root;
 21 }
 22 int update(int root,int pos,int val1,long long val2) {
 23     int newroot = tot++, tmp = newroot;
 24     c1[newroot] = c1[root] + val1;
 25     c2[newroot] = c2[root] + val2;
 26     int l = 1, r = n;
 27     while(l < r) {
 28         int mid = (l+r)/2;
 29         if(pos <= mid) {
 30             lson[newroot] = tot++;
 31             rson[newroot] = rson[root];
 32             newroot = lson[newroot];
 33             root = lson[root];
 34             r = mid;
 35         } else {
 36             rson[newroot] = tot++;
 37             lson[newroot] = lson[root];
 38             newroot = rson[newroot];
 39             root = rson[root];
 40             l = mid+1;
 41         }
 42         c1[newroot] = c1[root] + val1;
 43         c2[newroot] = c2[root] + val2;
 44     }
 45     return tmp;
 46 }
 47 long long query(int root,int K) {
 48     long long ret = 0;
 49     int l = 1, r = n;
 50     while(l < r) {
 51         int mid = (l+r)/2;
 52         if(c1[lson[root]] >= K) {
 53             r = mid;
 54             root = lson[root];
 55         } else {
 56             K -= c1[lson[root]];
 57             ret += c2[lson[root]];
 58             root = rson[root];
 59             l = mid+1;
 60         }
 61     }
 62     return ret + c2[root];
 63 }
 64 struct Node {
 65     int x;
 66     int D;
 67     int index;
 68     Node(int _x = 0,int _D = 0,int _index = 0) {
 69         x = _x;
 70         D = _D;
 71         index = _index;
 72     }
 73 } node[MAXN];
 74 bool cmp(Node a,Node b) {
 75     if(a.x != b.x)return a.x < b.x;
 76     else return a.D > b.D;
 77 }
 78 int y[MAXN];
 79 int ind[MAXN];
 80 bool cmp2(int a,int b) {
 81     return y[a] < y[b];
 82 }
 83 int rind[MAXN];
 84 int main() {
 85     int N,MM,X,P;
 86     while(~scanf("%d%d%d%d",&N,&MM,&X,&P)) {
 87         tot = 0;
 88         int cnt = 0;
 89         int cnty = 0;
 90         int L,R,D;
 91         for(int i = 0; i < N; i++) {
 92             scanf("%d%d%d",&L,&R,&D);
 93             y[cnty++] = D;
 94             ind[i] = i;
 95             node[++cnt] = Node(L,D,i);
 96             node[++cnt] = Node(R,-D,i);
 97         }
 98         sort(ind,ind+N,cmp2);
 99         for(int i = 0; i < N; i++)
100             rind[ind[i]] = i+1;
101         n = N;
102         sort(node+1,node+cnt+1,cmp);
103         T[0] = build(1,n);
104         for(int i = 1; i <= cnt; i++) {
105             if(node[i].D > 0)
106                 T[i] = update(T[i-1],rind[node[i].index],1,node[i].D);
107             else
108                 T[i] = update(T[i-1],rind[node[i].index],-1,node[i].D);
109         }
110         int x,a,b,c;
111         long long pre = 1;
112         while(MM--) {
113             scanf("%d%d%d%d",&x,&a,&b,&c);
114             int id = 0;
115             int l = 1, r = cnt;
116             while(l <= r) {
117                 int mid = (l+r)/2;
118                 if(node[mid].x < x || (node[mid].x == x && node[mid].D > 0)) {
119                     id = mid;
120                     l = mid+1;
121                 } else {
122                     r = mid-1;
123                 }
124             }
125             int K = (pre%c*a%c+b)%c;
126             if(K == 0) {
127                 printf("0
");
128                 pre = 0;
129                 continue;
130             }
131             long long ans = query(T[id],K);
132             if(pre > P)ans *= 2;
133             printf("%I64d
",ans);
134             pre = ans;
135         }
136     }
137     return 0;
138 }
View Code

Xor http://acm.hdu.edu.cn/showproblem.php?pid=4867

看不懂的。待补。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<vector>
  5 using namespace std;
  6 #define lson(x) ((x)<<1)
  7 #define rson(x) ((x)<<1|1)
  8 typedef long long LL ;
  9 const int P = 1000000007 ;
 10 const int MAXN = 10001 ;
 11 const int MAXLEN = 220;
 12 const int MAXM = 10 ; // 0<=x_i<2^30
 13 typedef short Node;
 14 typedef pair<short,int> CNode;
 15 CNode M[ MAXN << 2 ][ MAXLEN ];
 16 int Mlen[ MAXN << 2 ];
 17 int ID[ MAXN ] ;
 18 bool one[10];
 19 vector<short> ret;
 20 vector<short> split(int n){ //将n化为二进制 ai<=1000 2^10=1024 so 10bit
 21     for(int i=0;i<10;i++){
 22         one[i]=(n>>i)&1; //one 二进制逆序的
 23     }
 24     LL pre=0;
 25     ret.clear();
 26     for(int i=9;i>=0;i--){
 27         pre<<=1;
 28         if(one[i]){
 29             ret.push_back(pre<<4|i); //四位可以表示10 i<10
 30             pre|=1;
 31         }
 32     }
 33     ret.push_back(pre<<4);
 34     return ret;
 35 }
 36 short llen ;
 37 inline short merge( short a, short b ) {
 38     short ra = a&0xf, rb=b&0xf;
 39     short c=max( ra, rb);
 40     llen = min(ra,rb);
 41     a>>=4;
 42     b>>=4;
 43     a >>= (c-ra);
 44     b >>= (c-rb);
 45     return (a^b)<<4|c;
 46 }
 47 int a[ MAXN ];
 48 int max_size ;
 49 CNode tM[ MAXLEN*MAXLEN];
 50 void merge( CNode a[], int alen,  CNode b[], int blen,
 51             CNode c[], int &k) {
 52     k = 0;
 53     int tlen = 0;
 54     for( int i = 0; i < alen; ++ i) {
 55         short pre = a[i].first, now ;
 56         LL A = a[i].second;
 57         for(int j = 0; j < blen; ++ j) {
 58             now = merge( b[j].first, pre );
 59             int B = b[j].second;
 60             tM[tlen ++] = make_pair( now, (A *(1<<llen)%P)*B%P);
 61         }
 62     }
 63     sort( tM, tM + tlen );
 64     for(int i=0; i<tlen; ++i) {
 65         if(!i || tM[i].first != tM[i-1].first) {
 66             c[k++] = tM[i];
 67         } else c[k-1].second = (c[k-1].second + tM[i].second)%P;
 68     }
 69 }
 70 int msz;
 71 void build(int x, int l, int r) {
 72     int m=(l+r)>>1;
 73     Mlen[x] = 0;
 74     if(l+1==r) {
 75         ID[l]=x;
 76         vector< Node > v=split( a[l] );
 77         for(int i = 0; i < v.size(); ++ i) M[ x ][ Mlen[x] ++ ] = make_pair(v[i],1);
 78         msz=max(msz,Mlen[x]);
 79         return ;
 80     }
 81     build( lson(x), l, m);
 82     build( rson(x), m, r);
 83     merge( M[lson(x)], Mlen[lson(x)], M[rson(x)], Mlen[rson(x)], M[x],Mlen[x]);
 84     msz=max(msz,Mlen[x]);
 85 }
 86 void update( int pos, int val ) {
 87     vector< Node > v=split( val);
 88     a[pos ] =val ;
 89     int x = ID[pos ];
 90     Mlen[ x ] = 0;
 91     for(int i = 0; i < v.size(); ++ i) M[ x ][ Mlen[ x ] ++ ] = make_pair(v[i],1);
 92     for(x >>= 1; x ; x >>= 1) {
 93         merge( M[lson(x)], Mlen[lson(x)], M[rson(x)], Mlen[rson(x)], M[x],Mlen[x]);
 94     }
 95 }
 96 int count( int k) {
 97     LL ans = 0;
 98     for(int i = 0; i < MAXM; ++ i) {
 99         Node tar =  k<<4|i;
100         int j = lower_bound( M[1], M[1] + Mlen[1],  make_pair(tar, -1)) - M[1];
101         if( j<Mlen[1] && M[1][j].first == tar) {
102             ans += M[ 1 ][ j].second;
103             ans %= P;
104         }
105         k >>= 1;
106     }
107     return (int) ans;
108 }
109 int main() {
110     int n, m,T;
111     cin >> T ;
112     while(T--) {
113         cin >> n >> m;
114         for(int i=0; i<n; ++i) scanf("%d", a + i);
115         build( 1, 0, n );
116         for(int c=0; c<m; ++c) {
117             char op[ 4 ];
118             int a, b;
119             scanf("%s", op);
120             if(op[0] == 'C') {
121                 scanf("%d%d", &a, &b);
122                 update( a, b );
123             } else {
124                 scanf("%d", &a);
125                 printf("%d
", count(a) );
126             }
127         }
128     }
129     return 0;
130 }
View Code

Information Extraction http://acm.hdu.edu.cn/showproblem.php?pid=4868

模拟题。没研究。

  1 #include<cstdio>
  2 #include<cstring>
  3 using namespace std;
  4 const int N=10010;
  5 const int M=35;
  6 char html[M][N],stored[M][N],sta1[N][M];
  7 char mapping[M][M][2][M];
  8 int mapNum[M],sta2[N];
  9 void getHTML(int n) {
 10     int j,i=0,flag=1;
 11     char beginTag[M],tag[M];
 12     getchar();
 13     while(1) {
 14         html[n][i]=getchar();
 15         if(html[n][i]=='<') {
 16             j=0;
 17             while(html[n][++i]=getchar()) {
 18                 if(html[n][i]=='/')continue;
 19                 if(html[n][i]==' '||html[n][i]=='>')break;
 20                 tag[j++]=html[n][i];
 21             }
 22             tag[j]='';
 23             if(flag==1) {
 24                 strcpy(beginTag,tag);
 25                 flag=0;
 26             } else if(!strcmp(tag,beginTag)) {
 27                 html[n][++i]='';
 28                 return;
 29             }
 30         }
 31         i++;
 32     }
 33 }
 34 void getMapping(int n,int m) {
 35     int i,j;
 36     char mp[100];
 37     scanf("%s",mp);
 38     for(i=0; mp[i]!='-'; i++)
 39         mapping[n][m][0][i]=mp[i];
 40     mapping[n][m][0][i]='';
 41     for(j=0,i++; i<strlen(mp); i++,j++)
 42         mapping[n][m][1][j]=mp[i];
 43     mapping[n][m][1][j]='';
 44 }
 45 void getTag(int n,int i,char tag[]) {
 46     int j=0;
 47     while(1) {
 48         i++;
 49         if(html[n][i]=='/')continue;
 50         if(html[n][i]==' '||html[n][i]=='>')break;
 51         tag[j++]=html[n][i];
 52     }
 53     tag[j]='';
 54 }
 55 int getId(int n,int i,char id[]) {
 56     int j;
 57     id[0]='';
 58     char tmp[M];
 59     while(html[n][i]==' ') {
 60         j=0;
 61         while(html[n][++i]!='=')
 62             tmp[j++]=html[n][i];
 63         tmp[j]='';
 64         if(!strcmp(tmp,"id")) {
 65             i++;
 66             j=0;
 67             while(html[n][++i]!='"')
 68                 id[j++]=html[n][i];
 69             id[j]='';
 70         } else {
 71             i++;
 72             while(html[n][++i]!='"');
 73         }
 74         i++;
 75     }
 76     return i;
 77 }
 78 void store(int n,int i,int j,char tag[]) {
 79     stored[j][0]='';
 80     int k,y=0,flag=0,len=strlen(tag);
 81     for(i++;; i++) {
 82         k=0;
 83         if(html[n][i]=='<')
 84             for(; k<len; k++)
 85                 if(tag[k]!=html[n][i+1+k])break;
 86         if(k==len)flag++;
 87         k=0;
 88         if(html[n][i]=='<'&&html[n][i+1]=='/')
 89             for(; k<len; k++)
 90                 if(tag[k]!=html[n][i+2+k])break;
 91         if(k==len) {
 92             if(!flag) {
 93                 stored[j][y]='';
 94                 return;
 95             } else flag--;
 96         }
 97         stored[j][y++]=html[n][i];
 98     }
 99 }
100 bool isStructure(int n,int m) {
101     int i,j,k,ii,flag=0,top=-1;
102     char tag[M],id[M],tag2[M],id2[M];
103     int len1=strlen(html[n]);
104     for(i=k=0; i<len1;) {
105         ii=i;
106         while(html[n][i]==' '||html[n][i]=='
')i++;
107         while(html[m][k]!='<')k++;
108         getTag(n,i,tag);
109         getTag(m,k,tag2);
110         if(strcmp(tag,tag2)||html[n][i+1]!=html[m][k+1]) {
111             if(!strcmp(tag,tag2))sta2[top]++;
112             if(!flag) {
113                 return false;
114             }
115             while(html[m][k]!='>')k++;
116             i=ii;
117             continue;
118         }
119         if(html[n][i+1]=='/') { //</xx>
120             if(!sta2[top]) {
121                 i+=strlen(tag)+3;
122                 flag--;
123             } else sta2[top]--;
124             k+=strlen(tag)+3;
125         } else { //<xx>或者<xx/>
126             i+=strlen(tag)+1;
127             k+=strlen(tag2)+1;
128             if(html[n][i]==' ') { //有id
129                 if(html[m][k]!=' ') {
130                     if(!flag) {
131                         return false;
132                     }
133                     while(html[m][k]!='>')k++;
134                     i=ii;
135                     continue;
136                 }
137                 i=getId(n,i,id);
138                 k=getId(m,k,id2);
139                 if(strcmp(id,id2)) {
140                     if(!flag) {
141                         return false;
142                     }
143                     while(html[m][k]!='>')k++;
144                     i=ii;
145                     continue;
146                 }
147             }
148             for(j=0; j<mapNum[n]; j++)
149                 if(!strcmp(id,mapping[n][j][0]))
150                     break;
151             if(html[n][i]=='/') { //<xx/>
152                 i+=2;
153                 k+=2;
154             } else { //<xx>
155                 if(j!=mapNum[n]) { //需映射的id
156                     strcpy(sta1[++top],tag);
157                     flag++;
158                     sta2[top]=0;
159                     for(j=0; j<mapNum[n]; j++)
160                         if(!strcmp(id,mapping[n][j][0]))
161                             store(m,k,j,tag);
162                 }
163                 i++;
164                 k++;
165             }
166         }
167     }
168     return true;
169 }
170 void output(int n) {
171     int i,j,k,ii;
172     char tag[M];
173     int len1=strlen(html[0]);
174     for(i=0; i<len1;) {
175         while(i<len1&&html[0][i]!='<')
176             putchar(html[0][i++]);
177         if(i==len1)break;
178         getTag(0,i,tag);
179         for(j=0; j<mapNum[n]; j++)
180             if(!strcmp(tag,mapping[n][j][1]))
181                 break;
182         if(j==mapNum[n]) {
183             putchar(html[0][i++]);
184             continue;
185         } else {
186             int len=strlen(tag);
187             ii=i;
188             for(i+=len+1;; i++) {
189                 k=0;
190                 if(html[0][i]=='<'&&html[0][i+1]=='/')
191                     for(; k<len; k++)
192                         if(tag[k]!=html[0][i+2+k])break;
193                 if(k==len)break;
194             }
195             while(html[0][ii]!='>')
196                 putchar(html[0][ii++]);
197             putchar(html[0][ii++]);
198             printf("%s",stored[j]);
199             while(html[0][i]!='>')
200                 putchar(html[0][i++]);
201             putchar(html[0][i++]);
202         }
203     }
204 }
205 int main() {
206     int t;
207     while(~scanf("%d",&t)){
208         int cas=1;
209         while(t--) {
210             int i,j,n,m;
211             getHTML(0);
212             scanf("%d",&n);
213             for(i=1; i<=n; i++) {
214                 getHTML(i);
215                 scanf("%d",&mapNum[i]);
216                 for(j=0; j<mapNum[i]; j++)
217                     getMapping(i,j);
218             }
219             getHTML(n+1);
220             printf("Case #%d:
",cas++);
221             for(i=1; i<=n; i++)
222                 if(isStructure(i,n+1)) {
223                     output(i);
224                     break;
225                 }
226             if(i==n+1)printf("Can't Identify
");
227             else puts("");
228         }
229     }
230     return 0;
231 }
View Code

Turn the pokers http://acm.hdu.edu.cn/showproblem.php?pid=4869

快速幂求逆元,a%p,p是质数,a逆元是a^(p-2) %p。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 typedef __int64 LL;
 5 const int M=100010;
 6 const int mod=1000000009;
 7 LL Q_pow(LL a,LL n) {
 8     LL res=1,tmp=a;
 9     while(n) {
10         if(n&1) {
11             res*=tmp;
12             res%=mod;
13         }
14         tmp*=tmp;
15         tmp%=mod;
16         n>>=1;
17     }
18     return res;
19 }
20 LL C[M];
21 LL INV[M];
22 int main() {
23     for(int i=1; i<M; i++) {
24         INV[i]=Q_pow(i,mod-2);
25     }
26     int n,m,a;
27     while(~scanf("%d%d",&n,&m)) {
28         C[0]=1;
29         for(int i=1;i<=m;i++){
30             C[i]=C[i-1]*(m-i+1)%mod*INV[i]%mod;
31         }
32         int L=0,R=0,nl,nr,tmp;
33         for(int i=0;i<n;i++){
34             scanf("%d",&a);
35             tmp=min(m-L,a);
36             nr=L+tmp-(a-tmp);
37             tmp=min(R,a);
38             nl=R-tmp+(a-tmp);
39             if(nl>nr) swap(nl,nr);
40             if(L<=a&&a<=R){
41                 if(L%2==a%2){
42                     nl=0;
43                 }
44                 else{
45                     nl=min(nl,1);
46                 }
47             }
48             if((m-R)<=a&&a<=(m-L)){
49                 if((m-L)%2==a%2){
50                     nr=m;
51                 }
52                 else{
53                     nr=max(nr,m-1);
54                 }
55             }
56             if(L>=a) nl=min(nl,L-a);
57             if(m-R>=a) nr=max(nr,R+a);
58             L=nl;
59             R=nr;
60         }
61         int ans=0;
62         for(int i=L;i<=R;i+=2){
63             ans+=C[i];
64             ans%=mod;
65         }
66         printf("%d
",ans);
67     }
68     return 0;
69 }
View Code

Rating http://acm.hdu.edu.cn/showproblem.php?pid=4870

写出方程,高斯消元。题目意思我们可以推导出一个公式:E(i,j)=p*E(min(i+1,j),max(i+1,j))+(1-p)*E(max(i-2,0),j)+1....(1式)
我们可以将一式进行移项:得到 E(i,j)-p*E(min(i+1,j),max(i+1,j))-(1-p)*E(max(i-2,0),j)=1....(2式)

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 #define mt(a,b) memset(a,b,sizeof(a))
 6 using namespace std;
 7 const int M=420;
 8 double a[M][M],x[M];//方程的左边的矩阵和等式右边的值,求解之后x存的就是结果
 9 int equ,var;   //方程数和未知数个数
10 int Gauss() { //返回0表示无解,1表示有解
11     int i,j,k,col,max_r;
12     for(k=0,col=0; k<equ&&col<var; k++,col++) {
13         max_r=k;
14         for(i=k+1; i<equ; i++)
15             if(fabs(a[i][col])>fabs(a[max_r][col]))
16                 max_r=i;
17         if(k!=max_r) {
18             for(j=col; j<var; j++)
19                 swap(a[k][j],a[max_r][j]);
20             swap(x[k],x[max_r]);
21         }
22         x[k]/=a[k][col];
23         for(j=col+1; j<var; j++)a[k][j]/=a[k][col];
24         a[k][col]=1;
25         for(i=0; i<equ; i++)
26             if(i!=k) {
27                 x[i]-=x[k]*a[i][col];
28                 for(j=col+1; j<var; j++)a[i][j]-=a[k][j]*a[i][col];
29                 a[i][col]=0;
30             }
31     }
32     return 1;
33 }
34 int id[22][22];
35 int main() {
36     int cnt = 0;
37     for(int i = 0; i <= 20; i++)
38         for(int j = 0; j <= 20; j++) {
39             if(i > j)continue;
40             if(i == 20 && j == 20)continue;
41             id[i][j] = cnt++;
42         }
43     equ = var = cnt;
44     double p;
45     while(~scanf("%lf",&p)) {
46         mt(a,0);
47         for(int i = 0; i <= 20; i++)
48             for(int j = 0; j <= 20; j++) {
49                 if(i > j)continue;
50                 if(i == 20 && j == 20)continue;
51                 int u = id[i][j];
52                 a[u][u] = 1.0;
53                 if(i == 20 || j == 20) {
54                     x[u] = 0.0;
55                     continue;
56                 }
57                 x[u] = 1.0;
58                 int nx = i+1;
59                 if(nx <= j)
60                     a[u][id[nx][j]] -= p;
61                 else a[u][id[j][nx]] -= p;
62                 nx = max(0,i-2);
63                 a[u][id[nx][j]] -= (1-p);
64             }
65         Gauss();
66         printf("%.6f
",x[0]);
67     }
68     return 0;
69 }
View Code

Shortest-path tree http://acm.hdu.edu.cn/showproblem.php?pid=4871

用dij记录字典序最小的最短路径生成树,存pre里,其他的不懂。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<vector>
  4 #include<queue>
  5 #define mt(a,b) memset(a,b,sizeof(a))
  6 using namespace std;
  7 const int inf=0x3f3f3f3f;
  8 const int M=30010;
  9 int pre[M];
 10 int pre_w[M];
 11 class Dijkstra {  //  µ¥Ô´×î¶Ì·£¨dijkstra£©
 12     struct E {
 13         int u,v,next,w;
 14     } e[M<<2];
 15     struct Q {
 16         int id,w;
 17         friend bool operator <(Q a,Q b) {
 18             return a.w>b.w;
 19         }
 20     } node;
 21     priority_queue<Q> q;
 22     int le,head[M],dis[M];
 23     bool used[M];
 24 public:
 25     void init() {
 26         le=0;
 27         mt(head,-1);
 28     }
 29     int getvalue(int id) {
 30         return dis[id];
 31     }
 32     void add(int u,int v,int w) {
 33         e[le].u=u;
 34         e[le].v=v;
 35         e[le].w=w;
 36         e[le].next=head[u];
 37         head[u]=le++;
 38     }
 39     void solve(int s) {
 40         for(int i=0; i<M; i++) used[i]=true,dis[i]=inf;
 41         dis[s]=0;
 42         pre[s]=-1;
 43         while(!q.empty())q.pop();
 44         node.id=s;
 45         node.w=0;
 46         q.push(node);
 47         while(!q.empty()) {
 48             node=q.top();
 49             q.pop();
 50             int u=node.id;
 51             if(used[u]) {
 52                 used[u]=false;
 53                 for(int i=head[u]; ~i; i=e[i].next) {
 54                     int v=e[i].v;
 55                     int w=e[i].w;
 56                     if(used[v]&&dis[v]>w+dis[u]) {
 57                         dis[v]=w+dis[u];
 58                         node.id=v;
 59                         node.w=dis[v];
 60                         q.push(node);
 61                         pre[v]=u;
 62                         pre_w[v]=w;
 63                     }
 64                     else if(dis[v]==w+dis[u]&&u<pre[v]){
 65                         pre[v]=u;
 66                         pre_w[v]=w;
 67                     }
 68                 }
 69             }
 70         }
 71     }
 72 }gx;
 73 struct G{
 74     struct E{
 75         int u,v,w,next;
 76     }e[M<<1];
 77     int le,head[M];
 78     void init(){
 79         le=0;
 80         mt(head,-1);
 81     }
 82     void add(int u,int v,int w){
 83         e[le].u=u;
 84         e[le].v=v;
 85         e[le].w=w;
 86         e[le].next=head[u];
 87         head[u]=le++;
 88     }
 89 }g;
 90 bool vis[M];
 91 int ans1,ans2;
 92 int k;
 93 int size[M];
 94 int dfs(int u,int fa) {
 95     size[u]=1;
 96     for(int i=g.head[u];~i;i=g.e[i].next){
 97         int v=g.e[i].v;
 98         if(v!=fa&&!vis[v]){
 99             size[u]+=dfs(v,u);
100         }
101     }
102     return size[u];
103 }
104 int minn;
105 void getroot(int u,int fa,int totnum,int &root){
106     int maxx=totnum-size[u];
107     for(int i=g.head[u];~i;i=g.e[i].next){
108         int v=g.e[i].v;
109         if(v!=fa&&!vis[v]){
110             getroot(v,u,totnum,root);
111             maxx=max(maxx,size[v]);
112         }
113     }
114     if(minn>maxx){
115         minn=maxx;
116         root=u;
117     }
118 }
119 int dp[M];
120 int dpnum[M];
121 int pd[M];
122 int pdnum[M];
123 int maxdep;
124 void getpd(int u,int fa,int nw,int nd){
125     if(nd>k-1) return ;
126     maxdep=max(maxdep,nd);
127     if(nw>pd[nd]){
128         pd[nd]=nw;
129         pdnum[nd]=1;
130     }
131     else if(nw==pd[nd]){
132         pdnum[nd]++;
133     }
134     for(int i=g.head[u];~i;i=g.e[i].next){
135         int v=g.e[i].v;
136         if(v!=fa&&!vis[v]){
137             getpd(v,u,nw+g.e[i].w,nd+1);
138         }
139     }
140 }
141 void solve(int u) {
142     int totnum = dfs(u,-1);
143     minn = inf;
144     int root;
145     getroot(u,-1,totnum,root);
146     vis[root] = true;
147     for(int i = 0; i <= totnum; i++) {
148         dp[i] = 0;
149         dpnum[i] = 0;
150     }
151     dpnum[0] = 1;
152     for(int i = g.head[root]; i != -1; i = g.e[i].next) {
153         int v = g.e[i].v;
154         if(vis[v])continue;
155         maxdep = 0;
156         for(int j = 0; j <= size[v]; j++) {
157             pd[j] = 0;
158             pdnum[j] = 0;
159         }
160         pdnum[0] = 1;
161         getpd(v,u,g.e[i].w,1);
162         for(int j = 1; j <= maxdep && j < k; j++)
163             if(pdnum[j]&&dpnum[k-1-j]) {
164                 if(ans1 < pd[j]+dp[k-1-j]) {
165                     ans1 = pd[j]+dp[k-1-j];
166                     ans2 = pdnum[j]*dpnum[k-1-j];
167                 } else if(ans1 == pd[j]+dp[k-1-j])
168                     ans2 += pdnum[j]*dpnum[k-1-j];
169             }
170         for(int j = 1; j <= maxdep && j <= k; j++) {
171             if(dp[j] < pd[j]) {
172                 dp[j] = pd[j];
173                 dpnum[j] = pdnum[j];
174             } else if(dp[j] == pd[j])
175                 dpnum[j] += pdnum[j];
176         }
177     }
178     for(int i = g.head[root]; i != -1; i = g.e[i].next) {
179         int v = g.e[i].v;
180         if(vis[v])continue;
181         solve(v);
182     }
183 }
184 int main() {
185     int t,n,m,u,v,w;
186     while(~scanf("%d",&t)){
187         while(t--) {
188             scanf("%d%d%d",&n,&m,&k);
189             gx.init();
190             while(m--) {
191                 scanf("%d%d%d",&u,&v,&w);
192                 gx.add(u,v,w);
193                 gx.add(v,u,w);
194             }
195             gx.solve(1);
196             g.init();
197             for(int i = 2; i <= n; i++) {
198                 g.add(i,pre[i],pre_w[i]);
199                 g.add(pre[i],i,pre_w[i]);
200             }
201             ans1=ans2=0;
202             mt(vis,0);
203             solve(1);
204             printf("%d %d
",ans1,ans2);
205         }
206     }
207     return 0;
208 }
View Code

end

原文地址:https://www.cnblogs.com/gaolzzxin/p/3867397.html