来打卡啦!今天时间充裕,所以做两道题。
今天的幸运签:
今天还挺幸运的,我一定要考一次试!!!好在今天洛谷就有比赛。(不过成绩非常不理想)
先是K-联赛:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 700;
const int INF = 1000000000;
struct Edge {
int from, to, cap, flow;
};
bool operator < (const Edge& a, const Edge& b) {
return a.from < b.from || (a.from == b.from && a.to < b.to);
}
struct Dinic {
int n, m, s, t;
vector<Edge> edges; // 边数的两倍
vector<int> G[maxn]; // 邻接表,G[i][j]表示结点i的第j条边在e数组中的序号
bool vis[maxn]; // BFS使用
int d[maxn]; // 从起点到i的距离
int cur[maxn]; // 当前弧指针
void init(int n) {
for(int i = 0; i < n; i++) G[i].clear();
edges.clear();
}
void AddEdge(int from, int to, int cap) {
edges.push_back((Edge){from, to, cap, 0});
edges.push_back((Edge){to, from, 0, 0});
m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool BFS() {
memset(vis, 0, sizeof(vis));
queue<int> Q;
Q.push(s);
vis[s] = 1;
d[s] = 0;
while(!Q.empty()) {
int x = Q.front(); Q.pop();
for(int i = 0; i < G[x].size(); i++) {
Edge& e = edges[G[x][i]];
if(!vis[e.to] && e.cap > e.flow) {
vis[e.to] = 1;
d[e.to] = d[x] + 1;
Q.push(e.to);
}
}
}
return vis[t];
}
int DFS(int x, int a) {
if(x == t || a == 0) return a;
int flow = 0, f;
for(int& i = cur[x]; i < G[x].size(); i++) {
Edge& e = edges[G[x][i]];
if(d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap-e.flow))) > 0) {
e.flow += f;
edges[G[x][i]^1].flow -= f;
flow += f;
a -= f;
if(a == 0) break;
}
}
return flow;
}
int Maxflow(int s, int t) {
this->s = s; this->t = t;
int flow = 0;
while(BFS()) {
memset(cur, 0, sizeof(cur));
flow += DFS(s, INF);
}
return flow;
}
};
Dinic g;
const int maxt = 25 + 5;
int n, w[maxt], d[maxt], a[maxt][maxt];
inline int ID(int u, int v) { return u*n+v+1; }
inline int ID(int u) { return n*n+u+1; }
bool canWin(int team) {
// 计算team全胜后的总胜利场数
int total = w[team];
for(int i = 0; i < n; i++)
total += a[team][i];
for(int i = 0; i < n; i++)
if(w[i] > total) return false;
// 构图。s=0, 结点(u,v)的编号为u*n+v+1, 结点u的编号为n^2+u+1, t=n^2+n+1
g.init(n*n+n+2);
int full = 0;
int s = 0, t = n*n+n+1;
for(int u = 0; u < n; u++) {
for(int v = u+1; v < n; v++) {
if(a[u][v] > 0) g.AddEdge(s, ID(u,v), a[u][v]); // S到(u,v)的弧
full += a[u][v];
g.AddEdge(ID(u,v), ID(u), INF); // (u,v)到u的弧
g.AddEdge(ID(u,v), ID(v), INF); // (u,v)到v的弧
}
if(w[u] < total) g.AddEdge(ID(u), t, total-w[u]); // u到T的弧
}
return g.Maxflow(s, t) == full;
}
int main() {
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d%d", &w[i], &d[i]);
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
scanf("%d", &a[i][j]);
bool first = true;
for(int i = 0; i < n; i++)
if(canWin(i)) {
if(first) first = false; else printf(" ");
printf("%d", i+1);
}
printf("\n");
return 0;
}
P1277 拼字游戏:
#include<bits/stdc++.h>
using namespace std;
const int inf=1e9;
int val[5][5],lin[5],col[5],cr1,cr2;
int numl[5],numc[5],num1,num2;
struct node{int x,y;} sr[35];
void update(int x,int y,int v){
lin[x]+=v,col[y]+=v;
if(x==y) cr1+=v;
if(x+y==5) cr2+=v;
}
void calc(int x,int y,int v){
numl[x]+=v,numc[y]+=v;
if(x==y) num1+=v;
if(x+y==5) num2+=v;
}
bool check(int x,int y,int v){
if(v<=0) return 0;
if(lin[x]<v+numl[x]-1) return 0;
if(col[y]<v+numc[y]-1) return 0;
if(x==y&&cr1<v+num1-1) return 0;
if(x+y==5&&cr2<v+num2-1) return 0;
return 1;
}
inline int limit(int x,int y){
return min(min(lin[x]-numl[x],col[y]-numc[y]),min((x==y?cr1-num1:inf),(x+y==5?cr2-num2:inf)))+1;
}
inline bool cmp(const node&aa,const node&bb){
return limit(aa.x,aa.y)<limit(bb.x,bb.y);
}
void dfs(int pos){
int x=sr[pos].x,y=sr[pos].y;
if(x==4&&y==5){
for(int i=1;i<=4;++i)
if(lin[i]) return;
for(int i=1;i<=4;++i)
if(col[i]) return;
if(cr1||cr2) return;
for(int i=1;i<=4;++i){
for(int j=1;j<=4;++j)
cout<<val[i][j]<<" ";
cout<<endl;
}
exit(0);
}
if(numl[x]==1){
if(!check(x,y,lin[x])) return;
val[x][y]=lin[x],update(x,y,-val[x][y]),calc(x,y,-1);
dfs(pos+1);
update(x,y,val[x][y]),calc(x,y,1),val[x][y]=0;
return;
}
if(numc[y]==1){
if(!check(x,y,col[y])) return;
val[x][y]=col[y],update(x,y,-val[x][y]),calc(x,y,-1);
dfs(pos+1);
update(x,y,val[x][y]),calc(x,y,1),val[x][y]=0;
return;
}
if(num1==1&&x==y){
if(!check(x,y,cr1)) return;
val[x][y]=cr1,update(x,y,-val[x][y]),calc(x,y,-1);
dfs(pos+1);
update(x,y,val[x][y]),calc(x,y,1),val[x][y]=0;
return;
}
if(num2==1&&x+y==5){
if(!check(x,y,cr2)) return;
val[x][y]=cr2,update(x,y,-val[x][y]),calc(x,y,-1);
dfs(pos+1);
update(x,y,val[x][y]),calc(x,y,1),val[x][y]=0;
return;
}
int lmm=limit(x,y),l=lmm/3;
l=max(l,1);
calc(x,y,-1);
update(x,y,-l+1);
for(int i=l;i<=lmm;++i)
val[x][y]=i,update(x,y,-1),dfs(pos+1);
update(x,y,lmm);
for(int i=1;i<l;++i)
val[x][y]=i,update(x,y,-1),dfs(pos+1);
calc(x,y,1),val[x][y]=0,update(x,y,l-1);
}
int main(){
for(int i=1;i<=4;++i) cin>>lin[i],numl[i]=4;
for(int i=1;i<=4;++i) cin>>col[i],numc[i]=4;
cin>>cr1>>cr2,num1=num2=4;
for(int i=1,x,y,v;i<=4;++i){
cin>>x>>y>>v,++x,++y;
val[x][y]=v,update(x,y,-v),calc(x,y,-1);
}
int tt=0;
for(int i=1;i<=4;++i)
for(int j=1;j<=4;++j)
if(!val[i][j]) sr[++tt]=(node){i,j};
sort(sr+1,sr+tt+1,cmp);
sr[++tt]=(node){4,5};
dfs(1);
return 0;
}
记得三连哟!