• HDU 6041 I Curse Myself ——(仙人掌图,tarjan,转化)


      题解见这个博客:http://blog.csdn.net/ME495/article/details/76165039

      复杂度不太会算。。这个经典问题的解法需要注意,维护队列里面只有k个元素即可。另外,tarjan对无向图仙人掌图缩点(即只把所有环变成一个点)得注意一下(栈得手写才能实现要求,这是因为在这里割边不能被算进环内,而在有向图中,一个点也算是强连通分量的)。

      代码如下:

      1 #include <stdio.h>
      2 #include <algorithm>
      3 #include <string.h>
      4 #include <vector>
      5 #include <stack>
      6 #include <queue>
      7 using namespace std;
      8 const int N = 1000 + 5;
      9 typedef pair<int, int> pii;
     10 
     11 struct edge
     12 {
     13     int u, v, w;
     14 };
     15 int n, m, k;
     16 unsigned int tot;
     17 vector<edge> G[N];
     18 int dfs_clock, bcc_cnt, dfn[N];
     19 edge S[N*2];
     20 int top;
     21 vector<int> a[N*2];
     22 int ans[2][100000 + 50], sz[2];
     23 void init()
     24 {
     25     memset(dfn, 0, sizeof dfn);
     26     for(int i=1;i<=n;i++) G[i].clear();
     27     dfs_clock = 0;
     28     bcc_cnt = 0;
     29     tot = 0;
     30     top = 0;
     31     memset(ans, 0, sizeof ans);
     32     sz[0] = 1;
     33 }
     34 int test = 0;
     35 void tarjan(int u, int fa)
     36 {
     37     dfn[u] = ++dfs_clock;
     38     for(int i=0;i<G[u].size();i++)
     39     {
     40         edge e = G[u][i];
     41         int v = e.v, w = e.w;
     42         if(v == fa) continue;
     43         if(!dfn[v])
     44         {
     45             S[++top] = e;
     46             tarjan(v, u);
     47             top--;
     48         }
     49         else if(dfn[v] < dfn[u])
     50         {
     51             bcc_cnt++;
     52             a[bcc_cnt].clear();
     53             a[bcc_cnt].push_back(e.w);
     54             int top1 = top;
     55             for(;;)
     56             {
     57                 edge x = S[top1--];
     58                 a[bcc_cnt].push_back(x.w);
     59                 if(x.u == v) break;
     60             }
     61         }
     62     }
     63 }
     64 bool cmp(int x, int y) {return x > y;}
     65 struct node
     66 {
     67     int id, w;
     68     bool operator < (const node & temp) const
     69     {
     70         return w < temp.w;
     71     }
     72 };
     73 void merge(int *pre, int r, vector<int> &v, int *now)
     74 {
     75     priority_queue<node> Q;
     76     for(int i=0;i<v.size();i++) Q.push((node){0, pre[0] + v[i]});
     77     for(int i=0;i<k;i++)
     78     {
     79         sz[(r+1)&1] = i + 1;
     80         node temp = Q.top(); Q.pop();
     81         now[i] = temp.w;
     82         if(temp.id + 1 < sz[r&1]) Q.push((node){temp.id+1, temp.w-pre[temp.id]+pre[temp.id+1]});
     83         if(Q.empty()) break;
     84     }
     85 }
     86 
     87 int main()
     88 {
     89     int kase = 1;
     90     while(scanf("%d%d",&n,&m) == 2)
     91     {
     92         init();
     93         for(int i=1;i<=m;i++)
     94         {
     95             int u, v, w;
     96             scanf("%d%d%d",&u,&v,&w);
     97             G[u].push_back((edge){u, v, w});
     98             G[v].push_back((edge){v, u, w});
     99             tot += w;
    100         }
    101         scanf("%d",&k);
    102         tarjan(1, -1);
    103         for(int i=1;i<=bcc_cnt;i++)
    104         {
    105             sort(a[i].begin(), a[i].end(), cmp);
    106             merge(ans[(i-1)&1],i-1,a[i],ans[i&1]);
    107         }
    108         unsigned int sum = 0;
    109         for(int i=0;i<sz[bcc_cnt&1];i++)
    110         {
    111             sum += (unsigned int)(i+1) * (unsigned int)(tot-ans[bcc_cnt&1][i]);
    112         }
    113         printf("Case #%d: %u
    ",kase++,sum);
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    接口自动化(三)--读取json文件中的数据
    接口自动化(二)--操作Excel获取需要数据
    接口自动化(一)--概述
    pycharm(2016.3.2版本)导入工程文件执行程序时弹出Edit configuration
    使用Fiddler实现网络限速
    fiddler工具条、状态栏、请求信息栏各按钮的作用
    修改elementUI源码新增组件/修改组件
    DRF框架的基本组件
    django之原生SQL操作封装
    jqtree使用说明
  • 原文地址:https://www.cnblogs.com/zzyDS/p/7404272.html
Copyright © 2020-2023  润新知