QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#198836#4246. Cactus is Moneytuanlinh123WA 0ms27316kbC++204.0kb2023-10-03 17:37:522023-10-03 17:37:54

Judging History

你现在查看的是最新测评结果

  • [2023-10-03 17:37:54]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:27316kb
  • [2023-10-03 17:37:52]
  • 提交

answer

#include<bits/stdc++.h>
#define ll long long
#define pll pair<ll, ll>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ld long double
using namespace std;

struct point
{
    ll x, y;
    point operator + (const point & p) const 
    {
        return point{x+p.x, y+p.y};
    }
    point operator - (const point & p) const 
    {
        return point{x-p.x, y-p.y};
    }
    long long cross(const point & p) const 
    {
        return x*p.y - y*p.x;
    }
    bool operator < (const point & p) const 
    {
        if (x!=p.x) return x<p.x;
        return y<p.y;
    }
};

void reorder_polygon(vector <point> & P)
{
    ll pos=0;
    for(ll i=1; i<P.size(); i++)
        if(P[i].y<P[pos].y || (P[i].y==P[pos].y && P[i].x<P[pos].x))
            pos = i;
    rotate(P.begin(), P.begin() + pos, P.end());
}

vector <point> minkowski(vector<point> P, vector<point> Q)
{
    // the first vertex must be the lowest
    reorder_polygon(P);
    reorder_polygon(Q);
    // we must ensure cyclic indexing
    P.push_back(P[0]);
    P.push_back(P[1]);
    Q.push_back(Q[0]);
    Q.push_back(Q[1]);
    // main part
    vector<point> result;
    ll i=0, j=0;
    while(i<P.size()-2 || j<Q.size()-2)
    {
        result.push_back(P[i]+Q[j]);
        auto cross=(P[i+1]-P[i]).cross(Q[j+1]-Q[j]);
        if(cross>=0 && i<P.size()-2) i++;
        if(cross<=0 && j<Q.size()-2) j++;
    }
    return result;
}

bool ccw(point a, point b, point c)
{
    ll v=a.x*(b.y-c.y)+b.x*(c.y-a.y)+c.x*(a.y-b.y);
    return v>0;
}

vector <point> CVH(vector <point> a)
{
    ll n=a.size();
    sort(a.begin(), a.end());
    vector <point> cvh; 
    cvh.pb(a[0]); cvh.pb(a[1]);
    for (ll i=2; i<n; i++)
    {
        while (cvh.size()>1 && !ccw(cvh[cvh.size()-2], cvh[cvh.size()-1], a[i]))
                cvh.pop_back();
        cvh.pb(a[i]);
    }  
    for (ll i=n-2; i>=0; i--)
    {
        while (cvh.size()>1 && !ccw(cvh[cvh.size()-2], cvh[cvh.size()-1], a[i]))
                cvh.pop_back();
        cvh.pb(a[i]);
    }    
    cvh.pop_back();
    return cvh;
}

const ll maxn=3e5+5;
ll ptr;
vector <point> P[maxn];

bool cmp(ll a, ll b)
{
    return P[a].size()<P[b].size();
}

bool check[maxn], check2[maxn];
ll pa[maxn], dep[maxn];
vector <ll> A[maxn];
ll U[maxn], V[maxn], a[maxn], b[maxn];
priority_queue <ll, vector <ll>, function<bool(ll, ll)>> p(cmp);

void dfs(ll u)
{
    check[u]=1;
    for (ll idx:A[u])
    {
        if (idx==pa[u])
            continue;
        ll v=U[idx]==u ? V[idx] : U[idx];
        if (!check[v]) dep[v]=dep[u]+1, pa[v]=idx, dfs(v);
        else if (dep[v]<dep[u])
        {
            ll suma=a[idx], sumb=b[idx]; check2[idx]=1;
            vector <pll> p; p.pb({a[idx], b[idx]});
            ll crr=u;
            while (crr!=v)
            {
                ll idxn=pa[crr], crrn=U[idxn]==crr ? V[idxn] : U[idxn];
                check2[idxn]=1;
                suma+=a[idxn], sumb+=b[idxn];
                p.pb({a[idxn], b[idxn]}); crr=crrn;
            }
            for (ll i=0; i<p.size(); i++)
                P[ptr].pb({suma-p[i].fi, sumb-p[i].se});
            P[ptr]=CVH(P[ptr]);
            ptr++;
        }
    }
}


int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);
    ll n, m; cin >> n >> m;
    for (ll i=1; i<=m; i++)
    {
        cin >> U[i] >> V[i] >> a[i] >> b[i];
        A[U[i]].pb(i); A[V[i]].pb(i);
    }
    dfs(1);
    for (ll i=0; i<ptr; i++)
        p.push(i);
    while (p.size()>=2)
    {
        ll u=p.top(); p.pop();
        ll v=p.top();
        P[v]=minkowski(P[v], P[u]);
    }
    ll suma=0, sumb=0;
    for (ll i=1; i<=m; i++)
        if (!check2[i])
            suma+=a[i], sumb+=b[i];
    ll ans=1e18;
    for (point i:P[p.top()])
        ans=min(ans, (suma+i.x)*(sumb+i.y));
    cout << ans;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 27316kb

input:

3 3
1 2 0 1000
2 3 0 1000
3 1 1 1

output:

0

result:

ok 1 number(s): "0"

Test #2:

score: -100
Wrong Answer
time: 0ms
memory: 27144kb

input:

5 5
1 2 666 10
2 3 555 1000
3 1 444 345
1 4 222 234
2 5 333 123

output:

2644908

result:

wrong answer 1st numbers differ - expected: '1185480', found: '2644908'