QOJ.ac

QOJ

IDSubmission IDProblemHackerOwnerResultSubmit timeJudge time
#959#633818#9458. Triangulationhos_lyricucup-team3161Success!2024-10-13 16:59:412024-10-13 16:59:42

Details

Extra Test:

Time Limit Exceeded

input:

70
18
523990 661228
542094 867454
715348 957693
724847 921955
185285 504782
340889 164109
548808 628313
528132 176875
403401 165509
733176 362440
62653 306280
841647 146408
169951 295342
186442 591918
405268 31651
207390 724432
622724 775650
495011 800641
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 ...

output:

0 89323676
0 130331234
0 144675335
0 94323563
0 213829766
0 118195574
0 170444382
0 181328906
0 123390508
0 294695268
0 138491802
0 350786299
0 318187474
0 150111020
0 103700636
0 269957872
0 206602029
0 176150490
0 56950772
0 285570660
0 201339302
0 152004614
0 340341158
0 84076794
0 54258411
0 133...

result:


IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#633818#9458. Triangulationucup-team3161#TL 209ms85756kbC++204.8kb2024-10-12 16:15:052024-10-13 18:02:11

answer

#include <bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(int i=(a);i>=(b);--i)
#define int long long
using namespace std;

#define maxn 200005 
#define inf 0x3f3f3f3f

#define fi first
#define se second
#define pb push_back
#define mkp make_pair
typedef pair<int,int>pii;
typedef vector<int>vi; 


typedef double db;
const db eps=1e-8,pi=3.14159265358979323846;
int sgn(int x){return x<0?-1:x>0;}
int cmp(int a,int b){return sgn(a-b);}

struct P{
	int x,y,id;
	P(int x=0,int y=0):x(x),y(y){}
	P&operator +=(P o){return x+=o.x,y+=o.y,*this;}
	P&operator -=(P o){return x-=o.x,y-=o.y,*this;}
	P&operator *=(int o){return x*=o,y*=o,*this;}
	P&operator /=(int o){return x/=o,y/=o,*this;}
	friend P operator +(P a,P b){return a+=b;}
	friend P operator -(P a,P b){return a-=b;}
	friend P operator *(P a,int b){return a*=b;}
	friend P operator /(P a,int b){return a/=b;}
	friend bool operator <(P a,P b){return fabs(a.x-b.x)<eps?a.y<b.y:a.x<b.x;}
	friend bool operator ==(P a,P b){return cmp(a.x,b.x)==0 && cmp(a.y,b.y)==0;}
	friend bool operator !=(P a,P b){return !(a==b);}
	friend int operator %(P a,P b){return a.x*b.x+a.y*b.y;} // dot
	friend int operator *(P a,P b){return a.x*b.y-a.y*b.x;} // cross
	
//	P rot(db o){
//		db s=sin(o),c=cos(o),xx=x*c-y*s,yy=x*s+y*c;
//		x=xx,y=yy;return *this;
//	}
	P rot90(){swap(x,y),x=-x;return *this;}
	db ang(){return atan2(y,x);}
	db len(){return sqrt(x*x+y*y);}
	int len2(){return x*x+y*y;}
	
	int half(){return sgn(y)==1||(sgn(y)==0&&sgn(x)>=0);}
//	P unit(){return ((*this))/len();}
	
	void read(){cin>>x>>y;}
	void out(){cout<<"("<<x<<","<<y<<")"<<endl;}
};
bool cmp_dir(P a,P b){
	if(a.half()!=b.half())return a.half()<b.half();
	return sgn(a*b)>0;
}

db dis(P a,P b){return (a-b).len();}
int cross(P a,P b,P c){
	// (a->b)*(a->c)
	return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
int cmp3(P a,P b,P c){
	return sgn(cross(a,b,c));
}
bool in_tri(P a,P b,P c,P p){
	if(cmp3(a,b,c)<0) swap(b,c);
	return cmp3(a,b,p)>=0 && cmp3(b,c,p)>=0 && cmp3(c,a,p)>=0;
}

int n;
P p[233];

struct node{
    int x,y;
};
node operator +(node a,node b){
    if(a.x==b.x) return (node){a.x,a.y+b.y};
    if(a.x<b.x) return a;
    return b;
}
void operator +=(node&a,node b){
	a=a+b;
}

bool up[20][20][20];
bool hav[20][20][20];
int w[20][20];
node f[1<<18][20];
int rnk[25];

vector<P>convex(vector<P>a){
	int n=a.size(),m=0; if(n<=1)return a;
	sort(a.begin(),a.end());
	vector<P>st(n*2); int tp=0;
	For(i,0,n-1){
		while(tp>1 && cmp3(st[tp-2],st[tp-1],a[i])<=0)--tp;
		st[tp++]=a[i];
	}
	int t=tp;
	Rep(i,n-2,0){
		while(tp>t && cmp3(st[tp-2],st[tp-1],a[i])<=0)--tp;
		st[tp++]=a[i];
	}
	st.resize(tp-1);
	return st;
}

void work()
{
    cin>>n;
    For(i,1,n) cin>>p[i].x>>p[i].y,p[i].id=i;
    sort(p+1,p+n+1);
	For(i,1,n) rnk[p[i].id]=i;
	For(i,1,n) For(j,1,n) {
	//	w[rnk[i]][rnk[j]]=0;
		cin>>w[rnk[i]][rnk[j]];
	}
    For(i,1,n) p[i].id=i;


    For(i,1,n){
        For(j,1,n){
            For(k,1,n) if(k!=i && k!=j && i!=j){
                if(cmp3(p[i],p[j],p[k])>0) {
					up[i][j][k]=1;
				}else{
					up[i][j][k]=0;
				}
				hav[i][j][k]=0;
				For(x,1,n) if(x!=i && x!=j && x!=k){
					if(in_tri(p[i],p[j],p[k],p[x])){
						hav[i][j][k]=1;
					}
				}
            }
        }
    }


	vector<P>aa ;
	For(i,1,n) aa.pb(p[i]);
	aa=convex(aa);
	int S=1|(1<<(n-1));
	int T=S;
	for(auto a:aa){
		if(a.id!=1 && a.id!=n){
			if(up[1][n][a.id]) T|=(1<<(a.id-1));
			else S|=(1<<(a.id-1));
		}
	}

	For(s,0,(1<<n)-1)For(t,0,n)f[s][t]=(node){inf,0};

	int sum=0;
	For(i,1,aa.size()-1){
		sum+=w[aa[i-1].id][aa[i].id];
		if(aa[i].id==n) break;
	}

	f[S][0]=(node){0,1};
	queue< pii >q;
	q.push(mkp(S,0));
	while(q.size()){
		auto [s,lim]=q.front(); q.pop();
		vi o;
		For(i,0,n-1) if(s>>i&1) o.pb(i+1);
	//	for(int x:o) cout<<x<<" "; cout<<" S\n";
	//	cout<<"lim: "<<lim<<"\n";
	//	cout<<"value: "<<f[s][lim].x<<" "<<f[s][lim].y<<"\n";
		int sz=o.size();
		For(i,lim,sz-2){
			int l=o[i],r=o[i+1];
			For(k,l+1,r-1){
				if(up[l][r][k] && !hav[l][r][k]){
					node t=f[s][lim];
					t.x+=w[l][k]+w[k][r];
					int ss=(s|(1<<(k-1)));
					if(f[ss][i].x==inf) q.push(mkp(ss,i));
					f[ss][i]+=t;
				}
			}
			if(!i)continue;
			
			int x=o[i-1],y=o[i],z=o[i+1];
			if(!up[x][z][y] && !hav[x][z][y]) {
			//	cout<<"delete: "<<y<<"\n";
				node t=f[s][lim];
				t.x+=w[x][z];
				int ss=(s^(1<<(y-1)));
				if(f[ss][i-1].x==inf) q.push(mkp(ss,i-1));
				f[ss][i-1]+=t;
			}
		}
	}
	node res=(node){inf+1,0};
	For(i,0,n) res+=f[T][i];
	cout<<res.x+sum<<" "<<res.y<<"\n";
}
signed main()
{
   // freopen("my.out","w",stdout);

    int T;cin>>T;
    while(T--)work();
    return 0;
}
/*
1

5
0 0
0 2
2 0
2 2
1 1



*/