poj 3680 Intervals

  解题报告:http://blog.sina.com.cn/s/blog_6635898a0100pdlu.html

#include<iostream>
using namespace std;
const int nMax = 405;
const int eMax = 1500;
 
struct{
    int st, ed, w;
}inl[nMax];
struct{
    int v, cap, cost, next, re;
}edge[eMax];
int n, ans;
int k, edgeHead[nMax];
int que[nMax], pre[nMax], dis[nMax];
bool vis[nMax];
int hash[100005];
 
void addEdge(int u, int v, int ca, int co){
    edge[k].v = v;
    edge[k].cap = ca;
    edge[k].cost = co;
    edge[k].next = edgeHead[u];
    edge[k].re = k + 1;
    edgeHead[u] = k ++;
    edge[k].v = u;
    edge[k].cap = 0;
    edge[k].cost = -co;
    edge[k].next = edgeHead[v];
    edge[k].re = k - 1;
    edgeHead[v] = k ++;
}
 
bool spfa(){
    int i, head = 0, tail = 1;
    for(i = 0; i <= n; i ++){
        dis[i] = -1;
        vis[i] = false;
    }
    dis[0] = 0;
    que[0] = 0;
    vis[0] = true;
    while(head != tail){
        int u = que[head];
        for(i = edgeHead[u]; i != -1; i = edge[i].next){
            int v = edge[i].v;
            if(edge[i].cap && dis[v] < dis[u] + edge[i].cost){
                dis[v] = dis[u] + edge[i].cost;
                pre[v] = i;
                if(!vis[v]){
                    vis[v] = true;
                    que[tail ++] = v;
                    if(tail == nMax) tail = 0;
                }
            }
        }
        vis[u] = false;
        head ++;
        if(head == nMax) head = 0;
    }
    if(dis[n] <= 0) return false;
    return true;
}
 
void end(){
    int u, p;
    for(u = n; u != 0; u = edge[edge[p].re].v){
        p = pre[u];
        edge[p].cap -= 1;
        edge[edge[p].re].cap += 1;
        ans += edge[p].cost;
    }
}
 
int main(){
    int t, i, N, K;
    scanf("%d", &t);
    while(t --){
        memset(edgeHead, -1, sizeof(edgeHead));
        memset(hash, 0, sizeof(hash));
        scanf("%d%d", &N, &K);
        for(i = 0; i < N; i ++){
            scanf("%d%d%d", &inl[i].st, &inl[i].ed, &inl[i].w);
            hash[inl[i].st] = hash[inl[i].ed] = 1;
        }
        for(k = 1, i = 0; i <= 100000; i ++)     //  由于100000不大,所以我用hash离散化。
            if(hash[i] == 1)
                hash[i] = k ++;
        for(i = 0; i < N; i ++){                 //  线段的端点值,改为离散后的下标号。
            inl[i].st = hash[inl[i].st];
            inl[i].ed = hash[inl[i].ed];
        }
        n = k; k = 0;
        for(i = 0; i < n; i ++)                  //  建图。
            addEdge(i, i+1, K, 0);
        for(i = 0; i < N; i ++)
            addEdge(inl[i].st, inl[i].ed, 1, inl[i].w);
        ans = 0;
        while(spfa()) end();
        printf("%d\n", ans);
    }
    return 0;
}
View Code

 

posted @ 2013-08-16 16:53  yongren1zu  阅读(192)  评论(0编辑  收藏  举报