2019 计蒜之道 初赛 第一场
题解:
疑似贪心;
1 vector<int >out[maxn];///out[x]:存x指出去的点 2 int in[maxn];///in[x]:x的入度
需要删除的骨牌满足的条件为:
[1]:出度最大;
[2]:出度相同判断有无入度;
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define mem(a,b) memset(a,b,sizeof(a)) 4 #define ll long long 5 const int maxn=5e3+50; 6 7 int n; 8 vector<int >out[maxn]; 9 int in[maxn]; 10 bool vis[maxn]; 11 12 void Update() 13 { 14 int t=0; 15 for(int i=1;i <= n;++i) 16 { 17 if(vis[i] || out[i].size() < out[t].size()) 18 continue; 19 20 if(t == 0) 21 t=i; 22 if(out[i].size() > out[t].size() || in[i] > 0) 23 t=i; 24 } 25 for(int i=0;i < out[t].size();++i) 26 in[out[t][i]]--; 27 vis[t]=true; 28 } 29 int Solve() 30 { 31 mem(vis,false); 32 if(n <= 2) 33 return 0; 34 Update(); 35 Update(); 36 37 int ans=0; 38 for(int i=1;i <= n;++i) 39 if(!vis[i] && in[i] == 0) 40 ans++; 41 return ans; 42 } 43 int main() 44 { 45 // freopen("C:\\Users\\hyacinthLJP\\Desktop\\in&&out\\contest","r",stdin); 46 scanf("%d",&n); 47 for(int i=1;i < n;++i) 48 { 49 int x,y; 50 scanf("%d%d",&x,&y); 51 out[x].push_back(y); 52 in[y]++; 53 } 54 printf("%d\n",Solve()); 55 56 return 0; 57 }