zoukankan      html  css  js  c++  java
  • bzoj 3389

    题意:给定1维连续T<= 1000000个点,以及n<=10000个线段,求最少的线段覆盖该区间。。

    思路:很显然,贪心是可以做的。。不过这一题最有意思的是使可以转换为最短路模型。。

            如果一条线段覆盖了[l, r],可以连l->r+1,距离为1的边。。

            此外对于每个点i,连一条i->i-1,距离为0的边。。

            那么实际上就是求1->n+1的最短路。。

            感觉最短路模型还是很有意思的,跟2006北京赛区的最小割有点小像。。、

    code:

     1 #include  <bits/stdc++.h>
     2 using namespace std;
     3 typedef pair<int, int> pii;
     4 const int maxn = 1001000;
     5 struct edge{
     6      int v, w, next;
     7 } e[maxn << 1];
     8 int dis[maxn], last[maxn], n, m, tot;
     9 int use[maxn];
    10 
    11 inline void add(const int& u, const int& v, const int& w){
    12      e[tot] = (edge){v, w, last[u]}; last[u] = tot++;
    13 }
    14 
    15 void spfa(){
    16      priority_queue<pii, vector<pii>, greater<pii> > q;
    17      for (int i = 1; i <= n + 1; ++i) dis[i] = 0x3fffffff;
    18      pii tmp;
    19      memset(use, 0, sizeof(int) * (n + 10));
    20      q.push( make_pair(0, 1) ), dis[1] = 0;
    21      int u, v;
    22      while (!q.empty()){
    23           u = q.top().second; q.pop();
    24           if (use[u]) continue;
    25           use[u] = 1;
    26           if (u == n+1) return;
    27           for (int p = last[u]; p != -1; p = e[p].next){
    28                  v = e[p].v;
    29                  if (dis[u] + e[p].w < dis[v]){
    30                         dis[v] = dis[u] + e[p].w;
    31                         tmp.first = dis[v], tmp.second = v;
    32                         q.push(tmp);   
    33                  }
    34           }
    35      }
    36 }
    37 
    38 void solve(){
    39        tot = 0;
    40        memset(last, -1, sizeof(int) * (n + 10));
    41        int u, v;
    42        for (int i = 0; i < m; ++i){
    43               scanf("%d%d", &u, &v);
    44               add(u, v + 1, 1);
    45        }
    46        for (int i = 2; i <= n; ++i)
    47             add(i, i-1, 0); 
    48        spfa();
    49 //       for (int i = 1; i <= n; ++i) 
    50 //            printf("", dis[1]);
    51        int ans = dis[n+1];
    52        if (ans == 0x3fffffff) puts("-1");
    53        else cout << ans << endl;
    54 }
    55 
    56 int main(){
    57 //     freopen("a.in", "r", stdin);
    58      while (scanf("%d%d", &m, &n) != EOF){
    59           solve();
    60      }
    61 }
    View Code
  • 相关阅读:
    C语言指针入门
    c的动态内存管理
    汇编入门基础与helloworld
    汇编1
    汇编2——完整的例子集合
    算法与数据结构——选择,插入,希尔排序
    MySQL
    MySQL 笔记
    CSS样式优先级
    GIT使用笔记
  • 原文地址:https://www.cnblogs.com/yzcstc/p/4071483.html
Copyright © 2011-2022 走看看