Petrozavodsk Winter-2015. Xiaoxu Guo Contest 3.

版权声明:https://github.com/godspeedcurry 欢迎加好友哦 https://blog.csdn.net/qq_38677814/article/details/82707532

E 签到
给你三个点,求一个点P
使得
PA+2PB+3PC最小
化简 PA+PC+ 2(PB+PC)≥AC+2BC
当P在C点的时候取到

#include <bits/stdc++.h>
using namespace std;
double cal(double a,double b,double c,double d){
    return sqrt((a-c)*(a-c)+(b-d)*(b-d));
}
int main(){
    double a1,a2,b1,b2,c1,c2;
    while(cin>>a1>>a2>>b1>>b2>>c1>>c2){
        double ans=0;
        ans=cal(a1,a2,c1,c2)+2*cal(b1,b2,c1,c2);
        printf("%.15lf\n",ans);
    }
    return 0;
}

J subset sum
给定一个集合求前k个和最小的集合
经典题
注意负数的转化 先把所有负数求和 作为最小值
0的时候注意下 -1 -2 -3 2 3负数求和得到-6 可能出现-6 -(-1)-(-2)-(-3)这样的空集

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define mp(a,b) make_pair(a,b)
#define FORP(i,a,b) for(int i=a;i<=b;++i)
typedef pair<ll,ll> Pair;
priority_queue<Pair,vector<Pair>,greater<Pair> >PQ;
ll a[202000];
int main(){
    ll n,k;
    cin>>n>>k;
    memset(a,0x3f,sizeof(a));
    bool flag=false;//nonegative
    ll sum=0;
    FORP(i,1,n){
        cin>>a[i];  
        if(a[i]<0) sum+=a[i],a[i]=-a[i];
    }
    sort(a+1,a+1+n);
    if(sum<0) k--,cout<<sum<<endl;
    else flag=true;
    PQ.push(mp(a[1],1));
    while(k--){
        Pair u=PQ.top();
        PQ.pop();
        if(u.first+sum==0&&flag==false) flag=true,k++;//有负数并且和为0 特殊处理一下
        else cout<<u.first+sum<<endl;
        PQ.push(mp(u.first+a[u.second+1],u.second+1));
        PQ.push(mp(u.first-a[u.second]+a[u.second+1],u.second+1));
    }
    return 0;
}

给你一个二分图
可以染色成black or white 不同的黑白颜色权值不同
显然二分图一边的点不会超过一半
所以这边可以暴力染色
对于另一边枚举所有点,确定某点的颜色后与他相连的边的权值随之确定,
sum1 ,sum2
一种情况的答案为
temp=(sumi1+sumi2)(sumi3+sumi4)(sumi5+sumi6)*…
ans+=temp

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define mp(a,b) make_pair(a,b)
#define FORP(i,a,b) for(int i=a;i<=b;++i)
typedef pair<ll,ll> Pair;
#define maxn 200
#define pb push_back
const ll MOD=1e9+7;
vector<ll> v[maxn];
struct node{
    ll v[3][3];
}a[300][300];
int color[300];
void draw(int x,int c){
    color[x]=c;
    for(int i=0;i<v[x].size();++i){
        int to=v[x][i];
        if(color[to]==-1) draw(to,c^1);
    }
}
vector<ll> siz[2];
int cc[300];
ll ans=0;
void dfs(int choose,int now){
    if(now==siz[choose].size()){
        ll pro=1;
        for(int i=0;i<siz[choose^1].size();++i){
            int to=siz[choose^1][i];//右边的点
            ll sum1=1;
            ll sum2=1;
            for(int q=0;q<v[to].size();++q){
                int g=v[to][q];
                int nowcolor=cc[g];
                sum1=(sum1*a[to][g].v[0][nowcolor]%MOD);
                sum2=(sum2*a[to][g].v[1][nowcolor]%MOD);
            }
            pro=(pro*(sum1+sum2))%MOD;
        }
        ans=(ans+pro%MOD)%MOD;
        return;
    }
    int to=siz[choose][now];
    cc[to]=0;
    dfs(choose,now+1);
    cc[to]=1;
    dfs(choose,now+1);

}
int main(){
    int n,m;
    cin>>n>>m;
    memset(color,-1,sizeof color);
    memset(cc,-1,sizeof cc);
    FORP(i,1,m){
        ll from,to,va,vb,vc,vd;
        cin>>from>>to>>va>>vb>>vc>>vd;
        v[from].pb(to);
        v[to].pb(from);
        a[from][to].v[0][0]=va;
        a[from][to].v[0][1]=vb;
        a[from][to].v[1][0]=vc;
        a[from][to].v[1][1]=vd;
        a[to][from].v[0][0]=va;
        a[to][from].v[0][1]=vc;//注意这里
        a[to][from].v[1][0]=vb;//注意这里
        a[to][from].v[1][1]=vd;
    }
    FORP(i,1,n){
        if(color[i]==-1) draw(i,0); 
    }
    FORP(i,1,n){
        if(color[i]==1) siz[1].pb(i);
        else siz[0].pb(i);
    }
    int choose=siz[1].size()>=siz[0].size()?0:1;
    dfs(choose,0);
    cout<<ans<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38677814/article/details/82707532