详情请看:唐文斌在国家冬令营的讲课
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<queue> 6 #include<ctime> 7 using namespace std; 8 #define MAXN 210 9 #define MAXM 11000 10 const long long INF=10000000000000000ll; 11 long long ans=INF; 12 pair<long long,long long> e; 13 struct Edge 14 { 15 int x,y; 16 long long w1,w2; 17 }; 18 struct node 19 { 20 int num,id; 21 long long weight; 22 node *next; 23 }; 24 Edge edge[MAXM]; 25 node *graph[MAXN],memo[2*MAXM]; 26 int n,m,top=0; 27 bool use[MAXN]; 28 long long d[MAXN]; 29 priority_queue<pair<long long,pair<int,int> >,vector<pair<long long,pair<int,int> > >,greater<pair<long long,pair<int,int> > > > Q; 30 void add(int x,int y,long long w,int id) 31 { 32 node *p=&memo[top++]; 33 p->num=y; p->weight=w; p->id=id; p->next=graph[x]; graph[x]=p; 34 p=&memo[top++]; 35 p->num=x; p->weight=w; p->id=id; p->next=graph[y]; graph[y]=p; 36 } 37 pair<long long,long long> prim() 38 { 39 long long x=0,y=0; 40 long long w; 41 int i,u,v,id; 42 memset(use,0,sizeof(use)); 43 for(i=0;i<n;i++) 44 d[i]=INF; 45 d[0]=0; 46 while(!Q.empty()) Q.pop(); 47 Q.push(make_pair(0,make_pair(0,0))); 48 for(i=1;i<=n;i++) 49 { 50 if(Q.empty()) break; 51 u=Q.top().second.first; 52 id=Q.top().second.second; 53 Q.pop(); 54 while(!Q.empty()&&use[u]) 55 { 56 u=Q.top().second.first; 57 id=Q.top().second.second; 58 Q.pop(); 59 } 60 61 use[u]=1; 62 x+=edge[id].w1; 63 y+=edge[id].w2; 64 for(node *p=graph[u];p;p=p->next) 65 { 66 v=p->num; 67 if(!use[v]&&d[v]>p->weight) 68 { 69 d[v]=p->weight; 70 Q.push(make_pair(d[v],make_pair(v,p->id))); 71 } 72 } 73 } 74 if(x*y<ans) 75 { 76 ans=x*y; 77 e=make_pair(x,y); 78 } 79 return make_pair(x,y); 80 } 81 82 pair<long long,long long> make_graph(long long k1,long long k2) 83 { 84 memset(graph,0,sizeof(graph)); 85 int i; 86 top=0; 87 for(i=1;i<=m;i++) 88 add(edge[i].x,edge[i].y,edge[i].w1*k1+edge[i].w2*k2,i); 89 return prim(); 90 } 91 void make(pair<long long,long long> tree1,pair<long long,long long> tree2) 92 { 93 if(tree1==tree2) return ; 94 long long temp1=tree2.first-tree1.first; 95 long long temp2=tree1.second-tree2.second; 96 pair<long long,long long> tree3=make_graph(temp2,temp1); 97 if(tree3.first>tree1.first&&tree2.first>tree3.first&&tree3.second<tree1.second&&tree2.second<tree3.second) 98 { 99 make(tree1,tree3); 100 make(tree3,tree2); 101 } 102 } 103 104 void solve() 105 { 106 int i; 107 pair<long long,long long> tree1,tree2; 108 tree1=make_graph(1,0); 109 tree2=make_graph(0,1); 110 make(tree1,tree2); 111 printf("%I64d %I64d\n\n",e.first,e.second); 112 } 113 int main() 114 { 115 int i; 116 memset(edge,0,sizeof(edge)); 117 scanf("%d%d",&n,&m); 118 for(i=1;i<=m;i++) 119 scanf("%d%d%I64d%I64d",&edge[i].x,&edge[i].y,&edge[i].w1,&edge[i].w2); 120 solve(); 121 //cout<<clock()<<endl; 122 return 0; 123 }