又双叒叕把U盘忘在寝室了,所以把今下午的代码拷在这里
/*
reference:
translation:
有q次操作。每次会选定一个矩形区域。具体的每次给一组(x_1,y_1),(x_2,y_2)表示矩阵的左
下角和右上角。在这个矩阵所覆盖的每一个格子里,累加一个积木块。每个积木块可以可以抽
象为一个的正方体。现在,Venn想知道他们堆出来的物体的表面积。
solution:
【首先这并不是在线的询问,而是只询问一次,所以我们考虑对每个操作O(1)差分一下。】
1.n*m*q的暴力算法显然不可取,采用二维差分O(1)预处理,O(n^2)查询a[i][j]的高度。
2.如果这个位置有高度,ans+=2;(上表面和下表面),其他四个面看周围四个的心情
trigger:
note:
*二维差分
*表面积问题
record:
这道题开long long 会爆内存…………………………………………
date:
2019.08.26
*/
#define N 5001
int n,m,q;
int cnt[N][N];
int main(){
rd(n);rd(m);rd(q);
while(q--){
int x1,y1,x2,y2;rd(x1);rd(y1);rd(x2);rd(y2);
cnt[x1][y1]++;
cnt[x1][y2+1]--;
cnt[x2+1][y1]--;
cnt[x2+1][y2+1]++;
}
rep(i,1,n+1)
rep(j,1,m+1)
cnt[i][j]+=cnt[i-1][j]+cnt[i][j-1]-cnt[i-1][j-1];
long long ans=0;
rep(i,1,n+1){
rep(j,1,m+1){
if(cnt[i][j])ans+=2;
ans+=abs(cnt[i][j]-cnt[i-1][j])+abs(cnt[i][j]-cnt[i][j-1]);
}
}
printf("%lld\n",ans);
return 0;
}
/*
4 4 3
1 1 4 4
1 1 2 2
3 3 4 4
*/
//64
/*
4 4 1
1 1 2 2
*/
//16
dij
/*
reference:
translation:
solution:
trigger:
note:
*
record:
date:
2019.08.26
*/
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define dwn(i,a,b) for(int i=a;i>=b;--i)
template <typename T> inline void rd(T &x){x=0;char c=getchar();int f=0;while(!isdigit(c)){f|=c=='-';c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}x=f?-x:x;}
inline void write(int n){if(n==0)return;write(n/10);putchar(n%10+'0');}
#define mem(a,b) memset(a,b,sizeof(a))
#define ee(i,u) for(int i=head[u];i;i=e[i].next)
#define N 100010
int head[N],cnt,dis[N];
bool vis[N];
struct Edge{
int v,next,w;
}e[N<<1];
void add(int u,int v,int w){e[++cnt].v=v;e[cnt].w=w;e[cnt].next=head[u];head[u]=cnt;}
priority_queue<pair<int,int> > q;
int n,m,s;
inline void dij(){
mem(dis,0x3f);
mem(vis,0);
q.push(make_pair(0,1));
dis[1]=0;
while(!q.empty()){
int u=q.top().second;
q.pop();
if(vis[u])continue;
vis[u]=1;
ee(i,u){
int v=e[i].v,w=e[i].w;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
q.push(make_pair(-dis[v],v));
}
}
}
}
int main(){
rd(n),rd(m);
rep(i,1,m){
int x,y,z;rd(x),rd(y),rd(z);
add(x,y,z);
}
dij();
printf("%d ",dis[n]==0x3f3f3f3f?-1:dis[n]);
return 0;
}
*问你是否存在负环的时候(没说S点),要把每一个点都作为起点spfa一遍
rep(i,1,n){
if(spfa(i)){
printf("Yes\n");
exit(0);
}
}
printf("No\n");
最小费用最大流
/*给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用。
第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。
接下来M行每行包含四个正整数ui、vi、wi、fi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi),单位流量的费用为fi。
一行,包含两个整数,依次为最大流量和在最大流量情况下的最小费用。*/
/*
reference:
translation:
solution:
trigger:
note:
*
record:
date:
2019.08.26
*/
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define dwn(i,a,b) for(int i=a;i>=b;--i)
template <typename T> inline void rd(T &x){x=0;char c=getchar();int f=0;while(!isdigit(c)){f|=c=='-';c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}x=f?-x:x;}
inline void write(int n){if(n==0)return;write(n/10);putchar(n%10+'0');}
#define mem(a,b) memset(a,b,sizeof(a))
#define ee(i,u) for(int i=head[u];i;i=e[i].next)
#define N 100010
bool vis[N];
int n,m,s,t,x,y,z,f,cnt=1,maxflow,mincost;
int head[N],dis[N],pre[N],last[N],flow[N];
struct edge{int v,next,flow,cost;}e[N];
queue<int>q;
void add(int u,int v,int flow,int cost){
e[++cnt].v=v;e[cnt].flow=flow;e[cnt].cost=cost;e[cnt].next=head[u];head[u]=cnt;
e[++cnt].v=u,e[cnt].flow=0;e[cnt].cost=-cost;e[cnt].next=head[v];head[v]=cnt;
}
bool spfa(int s,int t){
mem(dis,0x7f);
mem(vis,0);
mem(flow,0x7f);
q.push(s);
vis[s]=1;
dis[s]=0;
pre[t]=-1;
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=0;
ee(i,u){
int v=e[i].v,cost=e[i].cost;
if(e[i].flow && dis[v]>dis[u]+cost){
dis[v]=dis[u]+cost;
pre[v]=u;
last[v]=i;
flow[v]=min(flow[u],e[i].flow);
if(!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
return pre[t]!=-1;
}
int main(){
#ifdef WIN32
freopen("zxfyzdl.txt","r",stdin);
#endif
rd(n),rd(m),rd(s),rd(t);
rep(i,1,m){
int u,v,cost,flow;rd(u),rd(v),rd(flow),rd(cost);
add(u,v,flow,cost);
}
while(spfa(s,t)){
int u=t;
maxflow+=flow[t];
mincost+=flow[t]*dis[t];
while(u!=s){
e[last[u]].flow-=flow[t];
e[last[u]^1].flow+=flow[t];
u=pre[u];
}
}
printf("%d %d",maxflow,mincost);
return 0;
}
/*
4 5 4 3
4 2 30 2
4 3 20 3
2 3 20 1
2 1 30 9
1 3 40 5
*/
//50 280
树的重心(WA)
/*
reference:
translation:
solution:
trigger:
note:
*
record:
date:
2019.08.26
*/
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define dwn(i,a,b) for(int i=a;i>=b;--i)
template <typename T> inline void rd(T &x){x=0;char c=getchar();int f=0;while(!isdigit(c)){f|=c=='-';c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}x=f?-x:x;}
inline void write(int n){if(n==0)return;write(n/10);putchar(n%10+'0');}
#define mem(a,b) memset(a,b,sizeof(a))
#define ee(i,u) for(int i=head[u];i;i=e[i].next)
#define N 10010
#define M
struct edge{
int v,next;
}e[N<<1];
int head[N],cnt,n,ans=INT_MAX,size[N];
inline void add(int u,int v){e[++cnt].v=v;e[cnt].next=head[u];head[u]=cnt;}
int dfs(int u,int fa){
size[u]=1;
int max_sub_tree=0;
ee(i,u){
int v=e[i].v;
if(v==fa)continue;
int t=dfs(v,u);
max_sub_tree=max(max_sub_tree,t);
size[u]+=t;
}
max_sub_tree=max(max_sub_tree,n-size[u]);
ans=min(ans,max_sub_tree);
return size[u]+1;
}
#undef int
int main(){
#define int long long
#ifdef WIN32
freopen("zhongxin.txt","r",stdin);
#endif
rd(n);
rep(i,1,n-1){
int u,v;rd(u),rd(v);
add(u,v),add(v,u);
}
dfs(1,0);
printf("%lld\n",ans);
//rep(i,1,n)printf("%lld ",size[i]);
return 0;
}
/*
9
1 2
1 7
1 4
2 8
2 5
4 3
3 9
4 6
*/
//4
toposort
- 判断是否有TOPO排序:记录的序列已经到达n个了
/*
reference:
translation:
solution:
trigger:
note:
*
record:
妈个鬼仙人啊,数组没开够,我还以为是哪里写错了 T^T
date:
2019.08.26
*/
#define N 100010
struct edge{
int v,next;
}e[N];
int head[N],cnt,n,m,tot,deg[N],topon[N];
void add(int u,int v){e[++cnt].v=v;e[cnt].next=head[u];head[u]=cnt;}
queue<int>q;
bool topo(){
rep(i,1,n)
if(!deg[i])
q.push(i);
while(!q.empty()){
int u=q.front();q.pop();
topon[++tot]=u;
ee(i,u){
int v=e[i].v;
if(--deg[v]==0)
q.push(v);
}
}
return tot==n;//////////////////////
}
int main(){
#ifdef WIN32
freopen("","r",stdin);
#endif
rd(n),rd(m);
rep(i,1,m){
int u,v;rd(u),rd(v);
add(u,v);deg[v]++;
}
if(topo()){
rep(i,1,tot)
printf("%d ",topon[i]);
}
else printf("-1\n");
return 0;
}
/*
3 3
1 2
2 3
1 3
*/
//1 2 3
floyd
note:
*如果有负权边,虽然a,b不连通,但之间的距离也会因为负权边的更新小于INF,
因为INF/2也是一个很大的数,所以就用>INF/2来代表不能连通
*一定要把dis[i][i]赋值为0!
*可能会有重边
rep(i,1,n)dis[i][i]=0;/////////////////////////////
dis[x][y]=min(dis[x][y],z);///////////////////////
if(dis[x][y]>0x3f3f3f3f/2)printf("impossible\n");
else printf("%d\n",dis[x][y]);
二分图最大匹配
/*
reference:
translation:
solution:
trigger:
note:
*
record:
date:
2019.08.26
*/
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define dwn(i,a,b) for(int i=a;i>=b;--i)
template <typename T> inline void rd(T &x){x=0;char c=getchar();int f=0;while(!isdigit(c)){f|=c=='-';c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}x=f?-x:x;}
#define mem(a,b) memset(a,b,sizeof(a))
#define ee(i,u) for(int i=head[u];i;i=m[i].next)
#define N 1010
int n1,n2,m,g[N][N],match[N],vis[N];
inline bool dfs(int u){
rep(v,1,n2){
if(g[u][v]==1 && vis[v]==0){
vis[v]=1;
if(match[v]==0 || dfs(match[v])){
match[v]=u;
return 1;
}
}
}
return 0;
}
#undef int
int main(){
#define int long long
#ifdef WIN32
freopen("","r",stdin);
#endif
rd(n1),rd(n2),rd(m);
while(m--){
int u,v;rd(u),rd(v);
g[u][v]=1;
}
int ans=0;//为新郎找姑娘
mem(match,0);//初始化一下,目前新娘还没有被占领
rep(i,1,n1){//枚举新郎
mem(vis,0);//每次都重做一遍二分图匹配
if(dfs(i))ans++;//恭喜i号新郎找到林妹妹
}
printf("%d",ans);
return 0;
}
/*
2 2 4
1 1
1 2
2 1
2 2
*/
//2
二分图染色
- col初始化为-1,通过~操作可得到-2和1
- 通过bfs来染色,注意要维护编号和一维值的关系时,可以make_pair
#define N 200010
int head[N],tot,col[N],s1,cnt,n,m;
bool vis[N];
struct edge{
int v,w,next;
}e[N<<1];
inline void add(int u,int v){e[++tot].v=v;e[tot].next=head[u];head[u]=tot;}
queue<pair<int,int> >q;
inline bool bfs(){
col[1]=1;
q.push(make_pair(1,1));
while(!q.empty()){
int u=q.front().first;
int color=q.front().second;
q.pop();
ee(i,u){
int v=e[i].v;
if(col[v]==-1){
col[v]=~color;
q.push(make_pair(v,col[v]));
}
else if(col[v]==col[u])return 0;
}
}
return 1;
}
int main(){
freopen("erfen.txt","r",stdin);
rd(n),rd(m);
rep(i,1,m){
int u,v;rd(u),rd(v);
add(u,v),add(v,u);
}
mem(col,-1);
if(bfs())printf("Yes\n");
else printf("No\n");
return 0;
}
/*
4 4
1 3
1 4
2 3
2 4
*/
//Yes