Submission #295713

#TimeUsernameProblemLanguageResultExecution timeMemory
295713stoyan_malininFriend (IOI14_friend)C++14
69 / 100
39 ms2808 KiB
#include "friend.h" //#include "grader.cpp" #include <queue> #include <vector> #include <cstring> #include <iostream> using namespace std; const int MAXN = 2015; int n; vector <int> graph[MAXN]; void constructGrahp(int n, int confidence[], int host[], int protocol[]) { for(int x = 1;x<=n;x++) { if(protocol[x]==0) { graph[ host[x] ].push_back(x); graph[x].push_back(host[x]); } else if(protocol[x]==1) { for(int y: graph[ host[x] ]) { graph[y].push_back(x); graph[x].push_back(y); } } else if(protocol[x]==2) { graph[x].push_back(host[x]); graph[ host[x] ].push_back(x); for(int y: graph[ host[x] ]) { graph[y].push_back(x); graph[x].push_back(y); } } } } namespace Subtask1 { bool can(int x, int mask) { for(int y: graph[x]) { if(((mask>>y)&1)==1) return false; } return true; } int rec(int x, int mask, int confidence[]) { if(x==n) return 0; int answer = rec(x+1, mask, confidence); if(can(x, mask)==true) answer = max(answer, confidence[x]+rec(x+1, (mask|(1<<x)), confidence)); return answer; } int solve(int n, int confidence[], int host[], int protocol[]) { constructGrahp(n, confidence, host, protocol); return rec(0, 0, confidence); } }; namespace Subtask2 { int solve(int n, int confidence[], int host[], int protocol[]) { int ans = 0; for(int x = 0;x<n;x++) ans += confidence[x]; return ans; } }; namespace Subtask3 { int solve(int n, int confidence[], int host[], int protocol[]) { int ans = 0; for(int x = 0;x<n;x++) ans = max(ans, confidence[x]); return ans; } }; namespace Subtask4 { int memo[MAXN][2]; int rec(int x, int last, bool take, int confidence[]) { if(memo[x][take]!=-1) return memo[x][take]; int answer = 0; if(take==true) { answer += confidence[x]; for(int y: graph[x]) { if(y==last) continue; answer += rec(y, x, false, confidence); } } else { for(int y: graph[x]) { if(y==last) continue; answer += max(rec(y, x, true, confidence), rec(y, x, false, confidence)); } } memo[x][take] = answer; return answer; } int solve(int n, int confidence[], int host[], int protocol[]) { memset(memo, -1, sizeof(memo)); constructGrahp(n, confidence, host, protocol); return max(rec(0, -1, false, confidence), rec(0, -1, true, confidence)); } }; namespace Subtask5 { struct Edge { int u, v, val; Edge(){} Edge(int u, int v, int val) { this->u = u; this->v = v; this->val = val; } }; struct MaxFlowGraph { int dist[MAXN]; int startInd[MAXN]; vector <Edge> edges; vector <int> graph[MAXN]; MaxFlowGraph(){} void addEdge(int u, int v, int val) { //cout << u << " " << v << '\n'; edges.push_back(Edge(u, v, val)); edges.push_back(Edge(v, u, 0)); graph[u].push_back(edges.size()-2); graph[v].push_back(edges.size()-1); } void BFS(int x) { queue <int> q; memset(dist, 0, sizeof(dist)); q.push(x); dist[x] = 1; while(q.empty()==false) { x = q.front(); q.pop(); for(int ind: graph[x]) { Edge e = edges[ind]; if(dist[e.v]==0 && e.val>0) { q.push(e.v); dist[e.v] = dist[x] + 1; } } } } int DFS(int x, int minVal, int sink) { if(x==sink) return minVal; for(int i = startInd[x];i<int(graph[x].size());i++) { Edge e = edges[ graph[x][i] ]; if(e.val>0 && dist[e.v]==dist[x]+1) { int flow = DFS(e.v, min(minVal, e.val), sink); if(flow!=0) { edges[ graph[x][i] ] .val -= flow; edges[ graph[x][i]^1 ].val += flow; return flow; } } startInd[x]++; } return 0; } int calcFlow(int source, int sink) { int maxFlow = 0; while(true) { BFS(source); if(dist[sink]==0) break; while(true) { int flow = DFS(source, MAXN, sink); if(flow==0) break; maxFlow += flow; } memset(startInd, 0, sizeof(startInd)); } return maxFlow; } }; int color[MAXN]; void dfsColor(int x, int col) { color[x] = col + 1; for(int y: graph[x]) { if(color[y]==0) { dfsColor(y, col^1); } } } int solve(int n, int confidence[], int host[], int protocol[]) { int S = n + 1, T = n + 2; MaxFlowGraph G; vector <pair <int, int>> all; for(int x = 1;x<n;x++) { if(protocol[x]==0) { all.push_back({host[x], x}); graph[x].push_back(host[x]); graph[ host[x] ].push_back(x); //G.addEdge(host[x], x, 1); } else { for(int y: graph[ host[x] ]) { all.push_back({y, x}); graph[x].push_back(y); graph[y].push_back(x); //G.addEdge(y.first, x, 1); } } } memset(color, 0, sizeof(color)); for(int x = 0;x<n;x++) { if(color[x]==0) dfsColor(x, 0); } for(pair <int, int> x: all) { int u = x.first; int v = x.second; if(color[u]>color[v]) swap(u, v); G.addEdge(u, v, 1); } for(int x = 0;x<n;x++) { if(color[x]==1) G.addEdge(S, x, 1); else G.addEdge(x, T, 1); } //cout << "K" << '\n'; return n - G.calcFlow(S, T); } }; int guessSubtask(int n, int confidence[], int host[], int protocol[]) { if(n<=10) return 1; bool subtask2 = true; for(int x = 1;x<n;x++) { if(protocol[x]!=1) { subtask2 = false; break; } } if(subtask2==true) return 2; bool subtask3 = true; for(int x = 1;x<n;x++) { if(protocol[x]!=2) { subtask3 = false; break; } } if(subtask3==true) return 3; bool subtask4 = true; for(int x = 1;x<n;x++) { if(protocol[x]!=0) { subtask4 = false; break; } } if(subtask4==true) return 4; bool subtask5 = true; for(int x = 1;x<n;x++) { if(protocol[x]==2) { subtask5 = false; break; } } if(subtask5==true) return 5; return -1; } int findSample(int _n,int confidence[],int host[],int protocol[]) { n = _n; int subtask = guessSubtask(n, confidence, host, protocol); if(subtask==2) return Subtask2::solve(n, confidence, host, protocol); if(subtask==3) return Subtask3::solve(n, confidence, host, protocol); if(subtask==1) return Subtask1::solve(n, confidence, host, protocol); if(subtask==4) return Subtask4::solve(n, confidence, host, protocol); if(subtask==5) return Subtask5::solve(n, confidence, host, protocol); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...