Codeforces 1038E Maximum Matching
阿新 • • 發佈:2018-09-09
連通圖 路徑 sdfas size 歐拉 sse asdf %d als
可能寫了個假算法
假設定義:含有一個歐拉路的圖為類歐拉圖
歐拉路的定義:一個無向連通圖中,存在一條路徑對所有邊都遍歷且僅遍歷一次;判斷方法:該連通圖中度為奇數的點的個數不能超過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); #defineleft 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