您的位置:首页 > 其它

BZOJ 2395 Time is Money

2016-03-07 14:13 309 查看
AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=2395

直接上题解:/article/6698190.html

很好看懂,感受到了画图的力量!点对投射到二维空间中去,感觉就会明了很多的样子...

不过复杂度什么的...虽然不能直接算出来,不过跑得很快。

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn=210;
const int maxm=10010;

struct Edge{
int u,v,w,t,c;
}e[maxm];

struct Point{
int x,y;
Point(){x=0,y=0;}
Point(int a,int b){x=a,y=b;}
}ans;

typedef Point Vector;
typedef long long ll;

Vector operator - (const Point &A,const Point &B){
return Vector(A.x-B.x,A.y-B.y);
}

ll Cross(const Vector &A,const Vector &B){
return (ll)A.x*B.y-(ll)A.y*B.x;
}

bool cmp(const Edge &A,const Edge &B){
return A.w<B.w;
}

int n,m;
int p[maxn];

int Find(int x){
int r=x,pre;
while(p[r]!=r) r=p[r];
while(x!=r)
pre=p[x],p[x]=r,x=pre;
return x;
}

Point Kruscal(){
Point res;
int cot=1,fx,fy;
for(int i=1;i<=n;i++) p[i]=i;
for(int i=1;i<=m && cot<n;i++){
fx=Find(e[i].u),fy=Find(e[i].v);
if(fx!=fy)
cot++,res.x+=e[i].c,res.y+=e[i].t,p[fx]=fy;
}
if((ll)ans.x*ans.y>(ll)res.x*res.y || ((ll)ans.x*ans.y==(ll)res.x*res.y && ans.x>res.x)) ans=res;
return res;
}

void Div(Point A,Point B){
for(int i=1;i<=m;i++)
e[i].w=e[i].c*(A.y-B.y)+e[i].t*(B.x-A.x);
sort(e+1,e+m+1,cmp);
Point C=Kruscal();
if(Cross(B-A,C-A)>=0) return ;
Div(A,C);Div(C,B);
}

int main(){
#ifndef ONLINE_JUDGE
freopen("2395.in","r",stdin);
freopen("2395.out","w",stdout);
#endif

Point A,B;
ans.x=1e9,ans.y=1e9;

scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d%d%d",&e[i].u,&e[i].v,&e[i].c,&e[i].t);
e[i].u++,e[i].v++;
}
for(int i=1;i<=m;i++) e[i].w=e[i].c;
sort(e+1,e+m+1,cmp);
A=Kruscal();
for(int i=1;i<=m;i++) e[i].w=e[i].t;
sort(e+1,e+m+1,cmp);
B=Kruscal();
Div(A,B);

printf("%d %d",ans.x,ans.y);

return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: