• hdu 6041 I Curse Myself


    题目:

      点这里OvO http://acm.hdu.edu.cn/showproblem.php?pid=6041

      2017 Multi-University Training Contest - Team 1 - 1009    

    题解:

      1.由于每条边只在一个环中,每个环必然要拿掉一条边,而这些边都是不重复的,那么最小生成树就对应的是通过求每个环中拿掉一条边,总和最大的组合对应的剩下的树(第k小生成树对应第k大组合剩下的树)。xjbdfs搜一下环,把每个环中的点放到一个集合中。

      2.然后对集合排序,xjb利用优先队列 ( 要注意优先队列中的元素的数量要保持和新集合的元素个数相同,以降低时间复杂度 ) 求最大的k(如果总数没k个那就不是k个)个组合(每个集合中取一个元素的组合)

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <algorithm>
      5 #include <cmath>
      6 #include <vector>
      7 #include <queue>
      8 
      9 using namespace std;
     10 
     11 typedef long long ll;
     12 
     13 const int N=1e4+55;
     14 const int M=2e3+44;
     15 const ll mod=(ll)pow(2,32);
     16 
     17 struct node{
     18     int u,v,d;
     19     int next;
     20 }edge[2*N];
     21 
     22 struct NODE
     23 {
     24     int v,now;    //value is (v), now add with (now)    
     25     friend bool operator<(NODE x,NODE y)
     26     {
     27         return x.v < y.v;
     28     }
     29 };//small to big
     30 
     31 priority_queue<NODE> Q;
     32 int num;
     33 int head[N];
     34 int n,m,k;
     35 ll ans;
     36 int snum;
     37 int stk[N],lstk;
     38 bool instk[M];
     39 vector<int> s[N];
     40 int val[M][M];
     41 vector<int> f,tmpf;
     42 ll sum_of_edge;
     43 ll du[M];
     44 
     45 bool cmp(int a,int b)
     46 {
     47     return a>b;
     48 }
     49 
     50 void addedge(int u,int v,int d)
     51 {
     52     edge[num].u=u;
     53     edge[num].v=v;
     54     edge[num].d=d;
     55     edge[num].next=head[u];
     56     head[u]=num++;
     57 }
     58 
     59 void init()
     60 {
     61     num=0;                  //记得初始化
     62        memset (head,-1,sizeof(head));
     63        memset(du,0,sizeof(du));
     64        snum=0;
     65     lstk=0;
     66     memset(instk,0,(n+4)*sizeof(bool));
     67     for(int i=1;i<=n;i++)
     68         s[i].clear();
     69     ans=0;
     70     sum_of_edge=0;
     71 }
     72           
     73 void dfs(int rt,int fa)
     74 {
     75     int v;
     76     if(instk[rt])
     77     {
     78         snum++; 
     79         int sav=rt;
     80         int sav_lstk=lstk;
     81         while(stk[lstk]!=rt)
     82         {
     83             s[snum].push_back(val[sav][stk[lstk]]);
     84             sav=stk[lstk--];
     85         }
     86         s[snum].push_back(val[sav][stk[lstk]]);
     87         lstk=sav_lstk;
     88         return ;
     89     }
     90     instk[rt]=1;
     91     stk[++lstk]=rt;
     92     for(int i=head[rt];i!=-1;i=edge[i].next)
     93     {
     94         v=edge[i].v;
     95         if(v==fa || du[v]==0) continue;
     96         du[rt]--; du[v]--;
     97         dfs(v,rt);
     98     }
     99     instk[rt]=0;
    100     lstk--;
    101 }
    102 
    103 void merge()
    104 {
    105     NODE q;
    106     int i,j,cnt;
    107     f.clear();
    108     if(snum==0)
    109     {
    110         f.push_back(0);
    111         return  ;
    112     }
    113     for(int i=0;i<s[1].size();i++)
    114         f.push_back(s[1][i]);
    115     for(int i=2;i<=snum;i++)
    116     {
    117         cnt=f.size()*s[i].size();
    118         if(cnt>k) cnt=k;
    119         while(!Q.empty())
    120             Q.pop();
    121         for(j=0;j<s[i].size();j++)
    122         {
    123             q.v=s[i][j]+f[0];
    124             q.now=0;
    125             Q.push(q);
    126         }
    127         tmpf.clear();
    128         while(cnt--)
    129         {
    130             q=Q.top();
    131             Q.pop();
    132             tmpf.push_back(q.v);
    133             if(q.now!=f.size()-1)
    134             {
    135                 q.v-=f[q.now];
    136                 q.now++;
    137                 q.v+=f[q.now];
    138                 Q.push(q);
    139             }
    140         }
    141         swap(f,tmpf);
    142     }
    143 //    cout<<"check merge
    ";
    144 //    for(int i=0;i<f.size();i++)
    145 //        printf("%d ",f[i]);
    146 //    printf("
    ");
    147 //    printf("end of check of merge
    ");
    148 }
    149 
    150 void solve()
    151 {
    152     dfs(1,-1);
    153     for(int i=1;i<=snum;i++)
    154         sort(s[i].begin(),s[i].end(),cmp);
    155 //    printf("check s
    ");
    156 //    for(int i=1;i<=snum;i++)
    157 //    {
    158 //        for(int j=0;j<s[i].size();j++)
    159 //            printf("%d",s[i][j]);
    160 //        printf("
    ");
    161 //    }
    162 //    printf("end of check of s
    ");
    163     merge();
    164 }          
    165 
    166 int main()
    167 {
    168     int cas=0,a,b,c;
    169     while(scanf("%d%d",&n,&m)!=EOF)
    170     {
    171         init();
    172         for(int i=1;i<=m;i++)
    173         {
    174             scanf("%d%d%d",&a,&b,&c);
    175             addedge(a,b,c);
    176             addedge(b,a,c);
    177             du[a]++; du[b]++;
    178             val[a][b]=val[b][a]=c;
    179             sum_of_edge+=c;
    180         }
    181         scanf("%d",&k);
    182         solve();
    183         for(int i=0;i<f.size();i++)
    184             ans=(ans+1ll*(i+1)*(sum_of_edge-f[i])%mod)%mod;
    185         printf("Case #%d: %lld
    ",++cas,ans%mod);
    186     }
    187     return 0;
    188 }
  • 相关阅读:
    Vue3源码系列之触发更新的实现
    Vue3源码系列之依赖收集的实现
    Vue3源码系列之reactiveApi实现
    删除链表的倒数第n个节点
    Shared_ptr 参考实现
    linux 目录结构 比较老
    C++11 bind function
    状态机DP
    尾递归
    秒杀系统的构建(2)
  • 原文地址:https://www.cnblogs.com/FxxL/p/7248088.html
Copyright © 2020-2023  润新知