您的位置:首页 > 其它

【bzoj 2395】: [Balkan 2011]Timeismoney

2015-03-12 16:57 232 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=2395

最小乘积生成树、、、?

好nb的样纸啊

感觉和分数规划的推导差不多。。。。。

复杂度是随机数据下期望。。。。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)
#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define INE(i,u) for(int i=head[u];~i;i=e[i].next)
#define LL long long
inline const int read()
{int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
////////////////////////////////////////////////
const int N=202;
const int M=10002;
int n,m;
struct edge{int u,v;LL x,y,w;}e[M];
struct Point{
int x,y;
Point(){}
Point(int x,int y):x(x),y(y){}
Point operator-(const Point &b)const{return Point(x-b.x,y-b.y);}
LL operator^(const Point &b)const{return x*b.y-y*b.x;}
}ans;
int fa
;
////////////////////////////////////////////////
bool cmp(edge A,edge B){return A.w<B.w;}
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
bool unio(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx==fy) return 0;
return fa[fx]=fy,1;
}
Point kruscal()
{
Point res=Point(0,0);
sort(&e[1],&e[m+1],cmp);
rep(i,0,n-1) fa[i]=i;
int blk=n;
rep(i,1,m)
{
if(unio(e[i].u,e[i].v))
{
res.x+=e[i].x;
res.y+=e[i].y;
if(--blk==1) break;
}
}
if(res.x*res.y < ans.x*ans.y || res.x*res.y == ans.x*ans.y && res.x<ans.x) ans=res;
return res;
}
void cal(Point A,Point B)
{
rep(i,1,m) e[i].w=e[i].y*(B.x-A.x) + e[i].x*(A.y-B.y);
Point C=kruscal();
if((A-C^B-C)>=0) return;
cal(A,C); cal(C,B);
}
////////////////////////////////////////////////
void input()
{
n=read(); m=read();
rep(i,1,m) e[i]=(edge){read(),read(),read(),read()};
}
void solve()
{
Point A,B;
ans.x=ans.y=0x3f3f3f3f;

rep(i,1,m) e[i].w=e[i].x;
A=kruscal();

rep(i,1,m) e[i].w=e[i].y;
B=kruscal();

cal(A,B);
printf("%d %d\n",ans.x,ans.y);
}
////////////////////////////////////////////////
int main()
{
//freopen("_.in","r",stdin); freopen("_.out","w",stdout);
input(),solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: