QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#633818 | #9458. Triangulation | ucup-team3161# | TL | 253ms | 85960kb | C++20 | 4.8kb | 2024-10-12 16:15:05 | 2024-10-12 16:15:09 |
Judging History
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
*/
这程序好像有点Bug,我给组数据试试?
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3564kb
input:
2 4 0 0 1 1 1 0 0 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 4 0 0 3 0 1 3 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0
output:
5 2 6 1
result:
ok 2 lines
Test #2:
score: 0
Accepted
time: 253ms
memory: 85960kb
input:
68 3 454 364 117 336 271 84 0 6 2 6 0 10 2 10 0 4 454 364 117 336 271 84 274 296 0 3 2 10 3 0 6 4 2 6 0 5 10 4 5 0 4 603 817 230 695 230 303 604 183 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 454 364 117 336 271 84 274 296 220 225 0 1 7 3 2 1 0 4 4 2 7 4 0 1 5 3 4 1 0 0 2 2 5 0 0 5 666667 788675 333173 78858...
output:
18 1 30 1 0 2 27 1 38 2 35 5 54 1 44 2 18 14 69 1 12 1 88 42 59 1 23 8 180 150 80 1 23 2 0 780 30 12 504 4550 30 4 19656 26888 29 6 26700 168942 24 88 22770 1098904 21 28 30816 7281984 24 27 15327 49789428 24 4 16338 342305320 21 48 42615 2410168190 22 360 44928 17309628327 1240448 1 2613579 1 19532...
result:
ok 68 lines
Extra Test:
score: 0
Extra Test Passed