hdu 5834 四面体 观察+暴力

Magic boy Bi Luo with his excited tree

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 767    Accepted Submission(s): 201


Problem Description
Bi Luo is a magic boy, he also has a migic tree, the tree has N nodes , in each node , there is a treasure, it's value is V[i], and for each edge, there is a cost C[i], which means every time you pass the edge i , you need to pay C[i].

You may attention that every V[i] can be taken only once, but for some C[i] , you may cost severial times.

Now, Bi Luo define ans[i] as the most value can Bi Luo gets if Bi Luo starts at node i.

Bi Luo is also an excited boy, now he wants to know every ans[i], can you help him?
 

 

Input
First line is a positive integer T(T104) , represents there are T test cases.

Four each test:

The first line contain an integer N(N105).

The next line contains N integers V[i], which means the treasure’s value of node i(1V[i]104).

For the next N1 lines, each contains three integers u,v,c , which means node u and node v are connected by an edge, it's cost is c(1c104).

You can assume that the sum of N will not exceed 106.
 

 

Output
For the i-th test case , first output Case #i: in a single line , then output N lines , for the i-th line , output ans[i] in a single line.
 

 

Sample Input
1 5 4 1 7 7 7 1 2 6 1 3 1 2 4 8 3 5 2
 

 

Sample Output
Case #1: 15 10 14 9 15
 

 

Author
UESTC
 

 

Source
 

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#include <set>
#define MM(a,b) memset(a,b,sizeof(a))
typedef long long ll;
typedef unsigned long long ULL;
const double eps = 1e-8;
const int inf = 0x3f3f3f3f;
const double pi=acos(-1);
using namespace std;
const int N=1e5+8;

struct Point{
   ll x,y,z,dis;
   int id;
   void read(){
       scanf("%lld%lld%lld",&x,&y,&z);
   }
   bool operator<(const Point &a) const{
       return this->dis<a.dis;
   }
}p[205],v[205];

Point operator-(Point a,Point b)
{
   return (Point){a.x-b.x,a.y-b.y,a.z-b.z};
}

double dis(Point a)
{
    return a.x*a.x+a.y*a.y+a.z*a.z;
}

Point cross(Point a,Point b)
{
   return (Point){a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x};
}

double area(Point a,Point b,Point c)
{
    return dis(cross(b-a,c-a));
}

double dot(Point a,Point b)
{
    return a.x*b.x+a.y*b.y+a.z*b.z;
}

bool onface(Point a,Point b,Point c,Point d)
{
    Point f=cross(a-b,c-b);
    return dot(f,d-b)==0;
}

int main()
{
    int cas,n,kk=0,x,y;
    scanf("%d",&cas);
    while(cas--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)   p[i].read();
        ll ans6=0,ans45=0;
        for(int i=1;i<=n;i++)
           for(int j=i+1;j<=n;j++)
           {
               ll len=dis(p[i]-p[j]);
               int cnt=0;
               for(int k=1;k<=n;k++)
               if(k!=i&&k!=j)
               {
                 if(dis(p[k]-p[i])-dis(p[k]-p[j])==0)
                   {
                       v[++cnt]=p[k];
                       v[cnt].dis=dis(p[k]-p[i]);
                   }
               }
               for(int k=1;k<=cnt;k++)
                  for(int w=k+1;w<=cnt;w++)
                 {
                     if((v[w].dis-v[k].dis)!=0) continue;
                     if(onface(p[i],p[j],v[k],v[w])) continue;
                     ll tmp=dis(v[w]-v[k]);

                     if((tmp-len)==0&&(len-v[k].dis)==0) ans6++;
                     else   ans45++;
                 }
           }
        ans45/=2;ans6/=6;
        printf("Case #%d: %lld\n",++kk,ans45+ans6);
    }
    return 0;
}

  分析:只想说两点:

1.两点连线的中垂线经过的整格点肯定是不多的,所以由此可以暴力。

2.T了话尝试去掉sqrt

posted @ 2016-08-16 23:40  快点说我帅  阅读(223)  评论(0编辑  收藏  举报