2022/2/3
2022/2/3
[P1402 酒店之王]( P1402 酒店之王 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) )
思路:
网络流建模
建立源点s,将房间与s建立一条流量为1的边
将房间与客人为1的点建立一条流量为1的边
n个客人自身连一条边,保证每个人只选一个
客人与喜欢的菜连一条边
p个菜与汇点t连一条流量为1的边
参考代码
#include<bits/stdc++.h>
#define ll long long
#define pii pair<long long , long long >
#define se second
#define pb push_back
#define pf push_front
#define si size()
#define db double
#define ls (p<<1)
#define rs (p<<1|1)
#define fi first
#define se second
using namespace std;
ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
inline void Prin(ll x){if(x < 0){putchar('-');x = -x;}if(x > 9) Prin(x / 10);putchar(x % 10 + '0');}
const int qs=10007;
const ll mod=998244353;
const ll inf=0x3f3f3f3f;
ll n,m,k,s,t;
ll head[qs],nxt[qs],to[qs],dis[qs],p;
//Dinic
ll level[qs],cur[qs];
//level是各点到终点的深度,cur为当前弧优化的增广起点
bool bfs(){//分层图
memset(level,-1,sizeof(level));
level[s]=0;
memcpy(cur,head,sizeof(head));
cur[s]=head[s];
queue<int> Q;
Q.push(s);
while(Q.si){
int fk=Q.front();
Q.pop();
for(int i=head[fk];i!=-1;i=nxt[i]){
if(dis[i]>0&&level[to[i]]==-1){
level[to[i]]=level[fk]+1;
Q.push(to[i]);
if(to[i]==t) return true;
}
}
}
return false;
}
ll dfs(int u,ll flow){
if(u==t) return flow;
ll ret=flow; //剩余的流量
for(int i=cur[u];i!=-1&&ret>0;i=nxt[i]){
cur[u]=i;// 当前弧优化
//如果还能流下去 并且 更深
if(dis[i]>0&&level[to[i]]==level[u]+1){
ll c=dfs(to[i],min(dis[i],ret));
if(!c) level[to[i]]=-1; //剪枝,出去增广完毕的点
ret-=c; //剩余的水流被用了c
dis[i]-=c; //减权重
dis[i^1]+=c; //反向边加权重
}
}
return flow-ret;//返回用掉的水流
}
//END
void add(int fx,int tx,ll dx){
to[p]=tx;
dis[p]=dx;
nxt[p]=head[fx];
head[fx]=p++;
//反向边
to[p]=fx;
dis[p]=0;
nxt[p]=head[tx];
head[tx]=p++;
}
void build_map(){
memset(head,-1,sizeof(head));
ll x;
s=0,t=m+k+n*2+1;
for(int i=1;i<=m;++i) add(s,i,1);
for(int i=1;i<=k;++i) add(m+n*2+i,t,1);
for(int i=1;i<=n;++i) add(m+i,m+n+i,1);
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
cin>>x;
if(x) add(j,m+i,1);
}
}
for(int i=1;i<=n;++i){
for(int j=1;j<=k;++j){
cin>>x;
if(x) add(m+n+i,m+n*2+j,1);
}
}
}
int main(){
cin>>n>>m>>k;
build_map();
ll ans=0;
ll can=0;
while(bfs()){
ans+=dfs(s,inf);
}
cout<<ans<<"\n";
return 0;
}
/*
*/
[ 郊区春游 ]( 郊区春游 (nowcoder.com) )
思路
状压dp
\(f[i][j]\)表示以第i个结尾,状态为j的最短路径
参考代码
#include<bits/stdc++.h>
#define ll long long
#define pii pair<long long , long long >
#define se second
#define pb push_back
#define pf push_front
#define si size()
#define db double
#define ls (p<<1)
#define rs (p<<1|1)
#define fi first
#define se second
using namespace std;
ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
inline void Prin(ll x){if(x < 0){putchar('-');x = -x;}if(x > 9) Prin(x / 10);putchar(x % 10 + '0');}
const int qs=(1<<15)+10;
const ll mod=998244353;
const ll inf=0x3f3f3f3f;
ll n,m,r,a[20],mp[207][207];
ll f[18][qs];// f[i][j]表示以第i个节点为结尾,状态为j的最短路径
void floyed(){
for(int k=1;k<=n;++k){
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
}
}
}
}
void dp(){
ll len=(1<<r)-1;
for(int i=1;i<=len;++i){
for(int j=0;j<r;++j) f[j][i]=inf;
}
for(int i=0;i<r;++i) f[i][(1<<i)]=0;
for(int i=1;i<=len;++i){//枚举状态
for(int j=0;j<r;++j){//枚举起点
if(!((1<<j)&i)) continue; //起点肯定走过
for(int k=0;k<r;++k){
if((1<<k)&i) continue; //终点没走过
f[k][i|(1<<k)]=min(f[k][i|(1<<k)],f[j][i]+mp[a[j]][a[k]]);
}
}
}
ll ans=inf;
for(int i=0;i<r;++i) ans=min(ans,f[i][len]);
cout<<ans<<"\n";
}
int main(){
n=read(),m=read(),r=read();
for(int i=0;i<r;++i) a[i]=read();
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j){
if(i==j) mp[i][j]=0;
else mp[i][j]=inf;
}
ll x,y,z;
while(m--){
cin>>x>>y>>z;
mp[x][y]=mp[y][x]=z;
}
floyed();
dp();
return 0;
}
/*
*/
前后端分离
简易:前端代码和后端代码分开写
传统的Java web 开发中,前端使用的是 JSP 开发,JSP不是由后端开发者独立完成的
前端-->HTML静态页面-->后端-->JSP
前端只需要独立编写客户端代码,后端只需要独立编写服务端代码提供数据接口即可。
前端通过Ajax请求来访问后端的数据接口,将Model展示到View中即可。
前后端开发者只需要提前约定好接口文档(URl、参数、数据类型),然后分别独立开发即可,前端可以造假数据进行测试,完全不需要以来于后端,最后完成前后端集成即可。真正实现了前后端应用的解耦合。
单体-->前端应用+后端应用
前端应用:负责数据展示和用户交互
后端应用:负责提供数据处理接口。
前端 HTML-->Ajax-->RESTful数据接口
实现技术
springboot + vue
使用 Spring Boot 进行后端应用开发,使用Vue进行前端应用开发。
[vue安装]( Vue开发环境搭建(Windows) - 知乎 (zhihu.com) )
Codeforces Round #768 (Div. 2)
[ C. And Matching ]( Problem - C - Codeforces (Unofficial mirror site, accelerated for Chinese users) )
先考虑-1的情况,明显只有 n=4,k=3的时候这一种情况
当n-1!=k时,直接用n-1 | k,得到的就是k,那么将剩下n-2个两两组合的或值变成0即可,考虑异或,会发现 x ^ n-1得到的值y,x|y=0,那么将n-1^k的值与0组合,其他数与异或值组合即可。
当n-1==k时,先 n-1 | n-2, 1 | 3,再用 n-1 ^ 3 与0组合,其他的同上。
参考代码
#include<bits/stdc++.h>
#define ll long long
#define pii pair<long long , long long >
#define se second
#define pb push_back
#define pf push_front
#define si size()
#define db double
#define ls (p<<1)
#define rs (p<<1|1)
#define fi first
#define se second
using namespace std;
ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
inline void Prin(ll x){if(x < 0){putchar('-');x = -x;}if(x > 9) Prin(x / 10);putchar(x % 10 + '0');}
const int qs=2e5+7;
const ll mod=998244353;
const ll inf=0x3f3f3f3f;
ll T,n,a[qs],k;
int main(){
T=read();
while(T--){
n=read(),k=read();
for(int i=0;i<n;++i) a[i]=0;
int p=n-1;
if(k==p){
if(n==4) cout<<"-1\n";
else{
cout<<p<<" "<<p-1<<"\n";
cout<<1<<" "<<3<<"\n";
cout<<(p^3)<<" "<<0<<"\n";
a[p]=a[p-1]=a[1]=a[3]=a[p^3]=a[0]=1;
for(int i=0;i<=p;++i){
if(a[i]) continue;
cout<<i<<" "<<(p^i)<<"\n";
a[i]=a[p^i]=1;
}
}
continue;
}
cout<<p<<" "<<k<<"\n";
if(k!=0) cout<<(p^k)<<" "<<0<<"\n";
a[p]=a[p^k]=a[k]=a[0]=1;
for(int i=0;i<=p;++i){
if(a[i]) continue;
cout<<i<<" "<<(p^i)<<"\n";
a[i]=a[p^i]=1;
}
}
return 0;
}
[ D. Range and Partition ]( Problem - D - Codeforces (Unofficial mirror site, accelerated for Chinese users) )
貌似二分+暴力枚举,明天补