ZOJ 3016 Cut(离散化+最小生成树)

地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3016

题意:给你n条线段,这些线段都平行于坐标轴,没有线段重叠,但是有交点,切割每条线段有一个值,现在这些线段形成一些封闭的区间,问怎样切割使得所有点之间有通路,且花费最小

分析:这题抛掉线段的外壳,很容易发现每个格子是一个点,外面的平面是一个点,点之间的边正好是切割线段的花费,答案明显的是最小生成树的值。。。不过这些线段怎么处理成小格子,头疼= =,一开始想放弃,不过仔细一想,好像可以做,大格子不好处理,那就处理最小的格子啊,把坐标离散化,然后做成n×m个格子,格子之间的边如果是一条线段,那么值就是切割线段的值,如果没有线段,那么值为零,现在建边就简单了,只要建每个格子上下左右的边就行。。。然后就呵呵了,具体看代码~ ~

代码:

/** head files*/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

/** some operate*/
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,l,h) for(int i=(l);i<=(h);++i)
#define DWN(i,h,l) for(int i=(h);i>=(l);--i)
#define foreach(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)
#define CLR(arr) memset(arr,0,sizeof(arr))
#define MAX3(a,b,c) max(a,max(b,c))
#define MAX4(a,b,c,d) max(max(a,b),max(c,d))
#define MIN3(a,b,c) min(a,min(b,c))
#define MIN4(a,b,c,d) min(min(a,b),min(c,d))

/** some const*/
#define N 1210
#define M N*N
#define PI acos(-1.0)
#define oo 1000000000
#define loo 1000000000000000000LL
#define eps 1e-8
/** some alias*/
typedef long long LL;

int dx[]={0,0,-1,1};
int dy[]={-1,1,0,0};
/** Global variables*/

/** some template names, just push ctrl+j to get it in*/
//getint 读入优化
//manacher 求最长回文子串
//pqueue 优先队列
//combk n元素序列的第m小的组合和
//pmatrix n个点的最大子矩阵
//suffixarray 后缀数组
//sbtree 平衡树
struct seg
{
    int x1,y1,x2,y2,c;
    void rd()
    {
        scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&c);
    }
};
struct Node
{
    int v,c;
    Node(){}
    Node(int v, int c):v(v),c(c){}
    bool operator<(const Node &a)const
    {
        return c>a.c;
    }
};
vector gx;
vector gy;
seg sg[N];
int g[N][N];
vector e[M];
bool vis[M];
priority_queue pq;
int no(int i, int j)
{
    return g[i*2][j*2];
}
void addedge(int u, int v, int c)
{
    e[u].push_back(Node(v,c));
    e[v].push_back(Node(u,c));
}
LL solve()
{
    while(!pq.empty())pq.pop();
    LL ret=0;
    for(pq.push(Node(0,0));!pq.empty();)
    {
        Node now=pq.top();
        pq.pop();
        if(vis[now.v])continue;
        ret=ret+now.c;
        foreach(it,e[now.v])
            if(!vis[it->v])pq.push(*it);
        vis[now.v]=1;
    }
    return ret;
}
int main()
{
    freopen("a","r",stdin);
    //freopen("wa","w",stdout);
    int n,m,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        gx.clear();
        gy.clear();
        REP(i,n)
        {
            sg[i].rd();
            gx.push_back(sg[i].x1);
            gx.push_back(sg[i].x2);
            gy.push_back(sg[i].y1);
            gy.push_back(sg[i].y2);
            if(sg[i].x1>sg[i].x2)swap(sg[i].x1,sg[i].x2);
            if(sg[i].y1>sg[i].y2)swap(sg[i].y1,sg[i].y2);
        }
        sort(gx.begin(),gx.end());
        sort(gy.begin(),gy.end());
        gx.resize(unique(gx.begin(),gx.end())-gx.begin());
        gy.resize(unique(gy.begin(),gy.end())-gy.begin());
        CLR(g);
        unsigned xi,yi;
        REP(i,n)
        {
            xi=lower_bound(gx.begin(),gx.end(),sg[i].x1)-gx.begin();
            yi=lower_bound(gy.begin(),gy.end(),sg[i].y1)-gy.begin();
            if(sg[i].x1sg[i].x2)break;
                    g[xi*2][yi*2+1]=sg[i].c;
                }
            }
            else if(sg[i].y1sg[i].y2)break;
                    g[xi*2+1][yi*2]=sg[i].c;
                }
            }
        }
        m=0;
        for(xi=1;xi


你可能感兴趣的:(图论,计算几何)