这套题目做完后,一定要反复的看!

代码经常出现的几个问题:

本机测试超时:

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 */
Code

相关文章: