这套题目做完后,一定要反复的看!
代码经常出现的几个问题:
本机测试超时:
1.init函数忘记写。
2.addedge函数写成add函数。
3.边连错了。
代码TLE:
1.前向星边数组开小.
2.用了memset,慎用。
1. CodeForces 498C Array and Operations
我发现cf上的网络流的建图思路都非常好,准备着重练习一下。
此题枚举每一个质因子,对每个质因子建图,确实是很好的思路。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define next Next 5 const int inf = 0x3f3f3f3f; 6 const int maxn=205; 7 int level[maxn]; 8 int iter[maxn]; 9 int head[maxn],tot; 10 struct edge{ 11 int to,cap,Next; 12 } e[5500]; ///此处应为边的两倍,加一条容量为0的反向边 13 void init(int n){ 14 15 for(int i = 0; i <= n; i++) head[i] = -1; 16 tot=0; 17 } 18 void add(int from,int to,int cap){ 19 e[tot].Next=head[from]; 20 e[tot].to=to; 21 e[tot].cap=cap; 22 head[from]=tot; 23 tot++; 24 } 25 void addedge(int from,int to,int cap){ 26 add(from,to,cap); 27 add(to,from,0); 28 } 29 void bfs(int s){ 30 memset(level,-1,sizeof(level)); 31 queue<int> q; 32 level[s]=0; 33 q.push(s); 34 while(!q.empty()){ 35 int v=q.front(); q.pop(); 36 for(int i=head[v];~i;i=e[i].Next){ 37 edge &ed=e[i]; 38 if(ed.cap>0&&level[ed.to]<0){ 39 level[ed.to]=level[v]+1; 40 q.push(ed.to); 41 } 42 } 43 } 44 } 45 int dfs(int v,int t,int f){ 46 if(v==t) return f; 47 for(int &i=iter[v];~i;i=e[i].Next){ 48 edge &ed=e[i]; 49 if(ed.cap>0&&level[v]<level[ed.to]){ 50 int d=dfs(ed.to,t,min(f,ed.cap)); 51 if(d>0){ 52 ed.cap-=d; 53 e[i^1].cap+=d; 54 return d; 55 } 56 } 57 } 58 return 0; 59 } 60 int max_flow(int s,int t){ 61 int flow=0; 62 while(1){ 63 bfs(s); 64 if(level[t]<0) return flow; 65 memcpy(iter,head,sizeof(iter)); 66 int f; 67 while((f=dfs(s,t,inf))>0){ 68 flow+=f; 69 } 70 } 71 } 72 73 //线性素数筛 74 const int N = 1e5 + 50; 75 int prime[N], num_prime = 0; 76 int isNotPrime[N]; 77 void is_prime(int N) 78 { 79 isNotPrime[0] = isNotPrime[1] = 1; 80 for(int i=2;i<N;i++) 81 { 82 if(!isNotPrime[i]) 83 { 84 prime[num_prime++] = i; 85 } 86 for(int j=0;j<num_prime&&i*prime[j]<N;j++) 87 { 88 isNotPrime[i*prime[j]] = 1; 89 if(!(i%prime[j])) 90 { 91 break; 92 } 93 } 94 } 95 return; 96 } 97 98 int a[111]; 99 vector<int> p[111]; 100 vector<int> cnt[111]; 101 int l[111][2]; 102 vector<int> big; ///大素数 103 int n, m; 104 int solve(int ans) 105 { 106 init(n + 1); 107 int s = 0, t = n + 1; 108 for(int j = 1; j <= n; j++) 109 { 110 int pos = lower_bound(p[j].begin(), p[j].end(), ans) - p[j].begin(); 111 if(pos < p[j].size() && p[j][pos] == ans) 112 { 113 // printf("%d %d %d\n", j, p[j][pos], cnt[j][pos]); 114 if(j & 1) addedge(s, j, cnt[j][pos]); 115 else addedge(j, t, cnt[j][pos]); 116 } 117 } 118 for(int j = 1; j <= m; j++) 119 { 120 int tmp = 100; 121 for(int k = 0; k < 2; k++) 122 { 123 // printf("%d\n", l[j][k]); 124 int pos = lower_bound(p[l[j][k]].begin(), p[l[j][k]].end(), ans) - p[l[j][k]].begin(); 125 // printf("%d %d %d\n", j, pos, cnt[l[j][k]][pos]); 126 if(pos < p[l[j][k]].size() && p[l[j][k]][pos] == ans) 127 { 128 tmp = min(tmp, cnt[l[j][k]][pos]); 129 } 130 else tmp = 0; 131 } 132 // printf("%d %d %d\n", l[j][0], l[j][1], tmp); 133 addedge(l[j][0], l[j][1], tmp); 134 } 135 // return 0; 136 return max_flow(s, t); 137 } 138 int main() 139 { 140 is_prime(1e5 + 5); 141 scanf("%d %d", &n, &m); 142 for(int i = 1; i <= n; i++) scanf("%d", &a[i]); 143 for(int i = 1; i <= n; i++) 144 { 145 for(int j = 2; j <= 1e5; j++) 146 { 147 if(j > a[i]) break; 148 if(a[i] % j == 0) p[i].push_back(j); 149 int tmp = 0; 150 while(a[i] % j == 0) 151 { 152 tmp++; 153 a[i] /= j; 154 } 155 if(tmp) cnt[i].push_back(tmp); 156 } 157 if(a[i] > 1) p[i].push_back(a[i]), cnt[i].push_back(1); 158 } 159 for(int i = 1; i <= m; i++) 160 { 161 int go1, go2; scanf("%d %d", &go1, &go2); 162 if(go1 % 2 == 0) swap(go1, go2); 163 l[i][0] = go1, l[i][1] = go2; 164 } 165 int ans = 0; 166 for(int i = 0; i < num_prime; i++) 167 { 168 ans += solve(prime[i]); 169 170 } 171 for(int i = 1; i <= n; i++) 172 { 173 int t = p[i].size(); 174 if(t == 0) continue; 175 if(p[i][t - 1] >= 1e5) big.push_back(p[i][t - 1]); 176 } 177 sort(big.begin(), big.end()); 178 big.erase(unique(big.begin(), big.end()), big.end()); 179 for(int i = 0; i < (int)big.size(); i++) 180 { 181 ans += solve(big[i]); 182 } 183 printf("%d\n", ans); 184 return 0; 185 } 186 /* 187 3 2 188 6 12 8 189 1 2 190 2 3 191 */