码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 1038E Maximum Matching

时间:2018-09-09 00:38:06      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:之间   random   题目   假设   using   tput   遍历   ctime   complex   

可能写了个假算法

 

假设定义:含有一个欧拉路的图为类欧拉图

欧拉路的定义:一个无向连通图中,存在一条路径对所有边都遍历且仅遍历一次;判断方法:该连通图中度为奇数的点的个数不能超过2,即为0或者2

 

题目解法:

对每一条数据a,b,c,想象成a点与b点之间连了一天值为c的边,则此图共有4个点

问题变成求图中一个合法的类欧拉图的边权和最大值

此值等于任意一个连通图的边权值之和,但一种情况除外,即此图中度为奇数的点个数超过2,对应此题中,度为奇数的点的个数即为4,此时连通图的所有边权和大于此图中合法的类欧拉图的边权和最大值,其之间的差值为图中一条边的权值,此边需要满足的条件为:如果这个连通图减去这条边,则可以形成一个合法的类欧拉图即可,此边的最小权值即为代码中的mx

 

 

 

 

#include<iostream>
#include<cstdio> 
#include<cmath>
#include<queue>
#include<vector>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#include<fstream>
#include<cstdlib>
#include<ctime>
#include<list>
#include<climits>
#include<bitset>
#include<random>
#include <ctime>
#include <cassert>
#include <complex>
#include <cstring>
#include <chrono>
using namespace std;
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("input.in", "r", stdin);freopen("output.in", "w", stdout);
#define left asfdasdasdfasdfsdfasfsdfasfdas1
#define tan asfdasdasdfasdfasfdfasfsdfasfdas
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
typedef long long ll;
typedef unsigned int un;
const int desll[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
const int mod=1e9+7;
const int maxn=1e5+7;
const int maxm=1e5+7;
const double eps=1e-4;
int m,n;
int ar[maxn];
int ans=0;
int num[10],sum[5];
int f[5][5],mx=1e5+7,all;
bool ma[5];
pair<pair<int,int>,int> pa[maxn];
int dfs(int x)
{
    all+=sum[x];
    ma[x]=1;
    int mid = num[x]%2;
    for(int i=1;i<=4;i++){
        if(f[x][i] && !ma[i])mid += dfs(i);
    }
    return mid;
}
void solve(int i)
{
    memset(ma,0,sizeof(ma));
    all=0;
    int x= dfs(i);
    all/=2;
    if(x==4)ans=max(ans,all-mx);
    else ans=max(ans, all);
}
int main()
{
    scanf("%d",&n);
    memset(num,0,sizeof(num));
    memset(sum,0,sizeof(sum));
    memset(f,0,sizeof(f));
    ans=0;
    for(int i=0;i<n;i++){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        sum[a]+=b;
        sum[c]+=b;
        num[a]++;
        num[c]++;
        f[a][c]++;
        f[c][a]++;
        pa[i]=make_pair(make_pair(a,b),c);
    }
    for(int i=0;i<n;i++){//求mx
        int a=pa[i].first.first,b=pa[i].first.second,c=pa[i].second;
        if(b<mx && a!=c){
            if(num[a]==1||num[c]==1||f[a][c]>1){
                mx=min(b,mx);
            }
            else{
                f[a][c]--;
                f[c][a]--;
                memset(ma,0,sizeof(ma));
                dfs(a);
                if(ma[c])mx=min(mx,b);
                f[c][a]++;
                f[a][c]++;
            }
        }
    }
    //cout<<"mx = "<<mx<<endl;

    for(int i=1;i<=4;i++)solve(i);

    printf("%d\n",ans);


    return 0;
}

 

Codeforces 1038E Maximum Matching

标签:之间   random   题目   假设   using   tput   遍历   ctime   complex   

原文地址:https://www.cnblogs.com/wa007/p/9610991.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!