尼罗河的水我的泪

news/2025/1/15 22:00:07/

20180321网络流二分图专题总结


这是一场没有任何不爆0机会的考试;
可怜的蒟蒻瑟瑟发抖在冷冷的冰雨中。没有达到我的预想,失分率太高,说明还是不够熟练,题切得也不够。不过也正常,我比别人切题要慢一些,而且时间也比别人少一些,只学了很短时间就考试考不好也是常事了,自己还是想开一点。

①对题分析

T1:早就想好了方法,但忘了二分图匈牙利算法的模板。趁现在赶紧打一次,以免下次搞事爆炸。

int find(int centre,int u)
{for(int i=1;i<=n;i++){if (i==centre||map[u][i]==0) continue;if (vis[i]) continue;vis[i]=1;if (link[i]==-1||find(centre,link[i])){link[i]=u;return 1;}}return 0;
}

(就是那种会写KM却不会写匈牙利的扭曲心情?)
然后就sb的写了一个奇怪方法(——工——!!)
KM.10 points;
果断挼掉。
codeforces387D
改之后AC的时候觉得自己太蠢了。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std;
int map[1001][1001],vis[1001],in[1001],out[1001],link[1001];
int n,m;
int ans=999999999;
int find(int centre,int u)
{for(int i=1;i<=n;i++){if (i==centre||map[u][i]==0) continue;if (vis[i]) continue;vis[i]=1;if (link[i]==-1||find(centre,link[i])){link[i]=u;return 1;}}return 0;
}
int solve(int centre)
{int cnt=0;int s=in[centre]+out[centre]-map[centre][centre];int se=2*n-1-s;memset(link,-1,sizeof(link));for(int i=1;i<=n;i++){if (i==centre) continue;memset(vis,0,sizeof(vis));if (find(centre,i)) cnt++;}se+=m-s-cnt;se+=n-1-cnt;return se;
}
int main()
{freopen("interesting.in","r",stdin);freopen("interesting.out","w",stdout);scanf("%d%d",&n,&m);int a,b;for(int i=1;i<=m;i++){scanf("%d%d",&a,&b);map[a][b]=1;in[b]++;out[a]++;}for(int i=1;i<=n;i++){ans=min(ans,solve(i));}printf("%d",ans);return 0;
}

T2:中等网络流,但我是模板侠。。。。虽然知道怎么做但是。。
哎。(···);
codeforces498C

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int inf=0x3f3f3f3f;
int a[1000001],x[1000001],y[1000001];
struct zk
{int u,v,next,w;
}e[5000001];
int prime[100001];
int mark[100001],dep[1000001],tot,cnt=0,head[1000001];void add(int u,int v,int w)
{e[cnt].u=u;e[cnt].v=v;e[cnt].w=w;e[cnt].next=head[u];head[u]=cnt++;e[cnt].u=v;e[cnt].v=u;e[cnt].w=0;e[cnt].next=head[v];head[v]=cnt++;
}
int bfs(int s,int t)
{queue<int> q;q.push(s);memset(dep,0,sizeof(dep));dep[s]=1;while(!q.empty()){int u=q.front();q.pop();if (u==t) return 1;for(int i=head[u];i!=-1;i=e[i].next){int v=e[i].v;if (!dep[v]&&e[i].w){q.push(v);dep[v]=dep[u]+1;}}}return dep[t]!=-1;
}
int dfs(int u,int t,int minn)
{if (u==t) return minn;int flow=0,ca=0;for(int i=head[u];i!=-1;i=e[i].next){int v=e[i].v;int w=e[i].w;if (w&&dep[v]==dep[u]+1){flow=dfs(v,t,min(minn-ca,e[i].w));e[i].w-=flow;e[i^1].w+=flow;ca+=flow;if (ca==minn) return ca;}}return ca;
}
void getprime(int n)
{memset(mark,-1,sizeof(mark));mark[1] = mark[0] = 0;tot=0;for (int i=2;i<n;i++){if (~mark[i])continue;tot++;prime[tot]=i;for(int j=2*i;j<n;j+=i)mark[j]=i;}
}int n,m;
bool judge(int num)  //这尼玛是什么?
{if (num<=sqrt(1e9)) return false;for (int i=0;i<=tot&&prime[i]*prime[i]<=num;i++) if (num%prime[i]==0) return false;return true;
}
int dinic(int s,int t)
{int ans=0;while(bfs(s,t))ans+=dfs(s,t,inf);return ans;
}
int num[100001];
int main()
{
//  freopen("operation.in","r",stdin);
//  freopen("operation.out","w",stdout);scanf("%d%d",&n,&m);int s=0,t=n+1;for(int i=1;i<=n;i++){scanf("%d",&a[i]);}for(int i=1;i<=m;i++){scanf("%d%d",&x[i],&y[i]);if (y[i]%2==1) swap(x[i],y[i]);}getprime(100000);int ans=0;for(int i=2;i<=sqrt(1e9);i++){if (~mark[i]) continue;memset(head,-1,sizeof(head));cnt=0;memset(num,0,sizeof(num));for(int j=1;j<=n;j++){while(a[j]%i==0){num[j]++;a[j]/=i;}}for(int j=1;j<=n;j+=2)add(s,j,num[j]);for(int j=2;j<=n;j+=2)add(j,t,num[j]);for(int j=1;j<=m;j++){int w=min(num[x[j]],num[y[j]]);add(x[j],y[j],w);}ans+=dinic(s,t);}memset(head,-1,sizeof(head));cnt=0;for(int i=1;i<=n;i+=2)if (judge(a[i])) add(s,i,1);for(int i=2;i<=n;i+=2)if (judge(a[i])) add(i,t,1);for(int i=1;i<=m;i++)if (a[x[i]]!=1&&a[x[i]]==a[y[i]]) add(x[i],y[i],1);ans+=dinic(s,t);printf("%d",ans);return 0;
}//这是一份RE的代码

T3:贪心+费用流。
codeforces315C2
这道题的模型并不明显,但是经过对题目性质的分析,我们就可以找到切入点。
贪心地想,为了在最短的步数之内达到理想状态,我们可知解题的两个性质:
首先,对于某一只与可配对鞋子不相邻的鞋子,它或它的配对鞋一定是移动或被移动过的。对于每一对可匹配的鞋子,它们不会同时被移动。
那么我们可以考虑,将网格内的点分为两个集合,每个集合内的点都互不相邻。然后从源点向其中一个集合的点连一条流量为1权值为0的边,另一个集合的点向汇点连一条流量为1权值为0的边。对于与源点相连的那个集合的点,向相邻的点连边,可以匹配的连权值为0的边,不可匹配的连权值为1的边。
跑一边最小费用最大流可以得到答案。

#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
#include <vector>
#include <algorithm>
#define maxn 1010
#define maxm 50000+10
#define inf 0x3f3f3f3f
#define LL long long
using namespace std;
struct zk
{int from, to, cap, flow, cost, next;
}e[maxm];
int head[maxn], cnt;
int dis[maxn];
int pre[maxn];
bool vis[maxn];
int n, m,k;
void add(int u, int v, int w, int c)
{zk E1 = {u,v, w, 0, c, head[u]};e[cnt] = E1;head[u] = cnt++;zk E2 = {v, u, 0, 0, -c, head[v]};e[cnt] = E2;head[v] = cnt++;
}
bool spfa(int s, int t)
{queue<int> q;memset(dis, inf, sizeof(dis));memset(vis, false, sizeof(vis));memset(pre, -1, sizeof(pre));dis[s] = 0;vis[s] = true;q.push(s);while(!q.empty()){int u = q.front();q.pop();vis[u] = false;for(int i = head[u]; i != -1; i = e[i].next){if(dis[e[i].to] > dis[u] + e[i].cost && e[i].cap > e[i].flow){dis[e[i].to] = dis[u] + e[i].cost;pre[e[i].to] = i;if(!vis[e[i].to]){vis[e[i].to] = true;q.push(e[i].to);}}}}return pre[t] != -1;
}
int minn(int s, int t)
{int cost= 0;while(spfa(s, t)){int minn = inf;for(int i = pre[t]; i != -1; i = pre[e[i^1].to]){minn = min(minn, e[i].cap - e[i].flow);}for(int i = pre[t]; i != -1; i = pre[e[i^1].to]){e[i].flow += minn;e[i^1].flow -= minn;cost += e[i].cost * minn;}}return cost;
}const int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
int a[3001][3001];
int main()
{scanf("%d%d",&n,&m);cnt=0;memset(head,-1,sizeof head);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){scanf("%d",&a[i][j]);}int S=0,T=(n*m+1);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) {if((i&1)==(j&1)) add((i-1)*m+j,T,1,0);else {add(S,(i-1)*m+j,1,0);for(int k=0;k<4;k++) {int x=i+dir[k][0],y=j+dir[k][1];if(x<1 || y<1 || x>n || y>m) continue;add((i-1)*m+j,(x-1)*m+y,1,(a[i][j]!=a[x][y]));}}}printf("%d",minn(0,T));return 0;
}

②错误原因

总之就是一点,回忆模板久远,耗时整场比赛。

③改进措施

对写过做过的学过的知识加强熟悉,宁愿多花点时间去敲一遍模板再做题,也不要直接复制粘贴模板只写建图。
毕竟,正规比赛的时候是没有模板可以套用的。
对所学知识进行一个新的自己的理解,提高自己代码AC率(代码毒瘤无法直视),慢慢让自己脱离写一道题20分钟,改一道题2个小时的困境(心累)。

④对以后的思考

觉得还是应该打好基础,不要图快,自己学不是别人学。别被别人的节奏带偏,毕竟自己和别人的学习规划不一样。
还是一步步来吧,文化知识和OI两不误,并不想一直都泡在机房,还是想学一些其他东西,虽然暂时OI学的要慢一点,但我觉得只要不慌一切都行。


http://www.ppmy.cn/news/864899.html

相关文章

vuex页面刷新数据丢失的解决办法

app.vue import store from ./storemounted () {// 解决vuex刷新丢失window.addEventListener("beforeunload",()>{ localStorage.setItem("userComMsg",JSON.stringify(store.state))});//在页面加载时读取localStorage里的状态信息if(localStorage.g…

React初学者需要的库从哪里下载?

在react官网下载react.js的方法介绍 1、访问react的github官方页面 访问地址为&#xff1a;Downloads | Reacthttps://react-cn.github.io/react/downloads.html 2、点击Download页面中的"Download Starter Kit"按钮&#xff0c;进行下载 学react的时候用到了babe…

raid5换硬盘显示ready_[原创]戴尔服务器raid5更换硬盘状态foreign怎么改成ready

磁盘阵列中单个硬盘出现问题时&#xff0c;“热备盘”会自动顶替“故障盘”。而“故障盘”不会自动恢复&#xff0c;这时&#xff0c;我们应该手工恢复阵列故障。 1、重新启动服务器&#xff0c;进入RAID卡BIOS设置界面。 2、进入PD Mgmt中查看故障盘的状态(foreign:外来的&…

魔兽世界转服务器显示待定,魔兽世界角色转移条件 魔兽世界角色转移待定怎么取消...

本文导航第2页&#xff1a;魔兽世界角色转移待定怎么取消 魔兽世界角色转移待定怎么取消 关于转移角色子账号的问题 Q&#xff1a;为什么我想要转入的服务器不在目标服务器的下拉列表内? A&#xff1a;请以列表显示为准&#xff0c;如果下拉列表中没有需要转入的服务器&#x…

魔兽世界怀旧服服务器最新阵营比例,《魔兽世界怀旧服》人口普查2019 阵营及服务器人口比例...

世界怀旧服已经有一段时间了&#xff0c;而具体有多少玩家在怀旧服中呢&#xff1f;不一样的服务器&#xff0c;和的玩家人数是不同的&#xff0c;而就在最近&#xff0c;魔兽世界怀旧服进行了一次玩家统计&#xff0c;那么接下来&#xff0c;就为大家介绍一下魔兽世界怀旧服20…

Mysql——》参数

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…

魔兽怀旧服转服服务器维护多久,魔兽世界怀旧服转服服务开启 怀旧服转服条件一览...

魔兽世界怀旧服此前虽然有过转服内容&#xff0c;但是上次转服仅仅只开放了部分大区&#xff0c;属于为了缓解服务器热度过高而做出的措施&#xff0c;因此也有很多玩家渴望真正的转服服务。现在官方发出公告&#xff0c;《魔兽世界》经典怀旧服付费角色转移即将开启&#xff0…

魔兽同服务器物品,《魔兽世界》怀旧服:这是给你的转服物资必备清单

自从最近免费定向转服的消息放出之后&#xff0c;就有许多玩家已经在第一时间转入到了新服&#xff0c;开始享受"不排队"的快乐体验&#xff0c;还有一部分玩家正在观望&#xff0c;今天小编就给大家带来了这样一份转服必备的物资清单&#xff0c;让我们一起来看看有…