一道网络流的题目:1006 Tricks Device,题意求隔断多少边可以去除最短路,其实就是裸的最小割,这里把流量限定为边的个数,跑一边网络流就可以了,比较思维的是dij算法的改造,改造求他最短路的长度。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<vector>
#define maxn 2010
#define INF 1e9
using namespace std;
struct edge{
edge(){};
edge(int from,int to,int val,int flow):from(from),to(to),val(val),flow(flow){}
int from,to,val,flow;
};
int n,m,f,d;
vector<edge>p;
vector<int>num[maxn];
bool visit[maxn];
bool vis[maxn];
int dis[maxn];
int cur[maxn];
int a[maxn][maxn];
int cnt[maxn][maxn];
int dist[maxn];
int number[maxn];
void add(int x,int y,int z){
p.push_back(edge(x,y,z,0));
p.push_back(edge(y,x,0,0));
int xx=p.size();
num[x].push_back(xx-2);
num[y].push_back(xx-1);
}
bool bfs(int s,int t){
int i,j;
memset (visit,0,sizeof(visit));
queue<int>qq;
qq.push(s);
dis[s]=0;
visit[s]=1;
while (!qq.empty()){
int u=qq.front();
qq.pop();
for (i=0;i<num[u].size();i++){
edge& e=p[num[u][i]];
if (!visit[e.to]&&e.val>e.flow){
visit[e.to]=1;
dis[e.to]=dis[u]+1;
qq.push(e.to);
}
}
}
return visit[t];
}
int dfs(int x,int t,int val){
if (x==t||val==0){
return val;
}
int flow=0,f;
for (int& i=cur[x];i<num[x].size();i++){
edge& e=p[num[x][i]];
if (dis[x]+1==dis[e.to]&&(f=dfs(e.to,t,min(val,e.val-e.flow)))>0){
e.flow+=f;
p[num[x][i]^1].flow-=f;
flow+=f;
val-=f;
if (val==0)break;
}
}
return flow;
}
int dinic(int s,int t){
int flow=0;
while (bfs(s,t)){
memset (cur,0,sizeof(cur));
flow+=dfs(s,t,INF);
}
return flow;
}
int dij(){
int i,j;
memset (dist,0x3f,sizeof(dist));
memset (number,0x3f,sizeof(number));
memset(vis,0,sizeof(vis));
number[1]=dist[1]=0;
for (i=1;i<=n;i++){
int mark=-1;
int minn=INF;
for (j=1;j<=n;j++){
if (!vis[j]&&dist[j]<minn){
minn=dist[j];
mark=j;
}
}
if (mark==-1) break;
vis[mark]=1;
for (j=1;j<=n;j++) if (!vis[j]&&a[mark][j]){
if (dist[j]>minn+a[mark][j]){
dist[j]=minn+a[mark][j];
number[j]=number[mark]+1;
}
else if (dist[j]==minn+a[mark][j])number[j]=min(number[j],number[mark]+1);
}
}
return number[n];
}
int main(){
int i,j,k,l,x,y,z,t;
while (scanf("%d%d",&n,&m)!=EOF){
memset (a,0x3f,sizeof(a));
memset (cnt,0,sizeof(cnt));
for (i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
if (z<a[x][y]){
a[x][y]=a[y][x]=z;
cnt[x][y]=cnt[y][x]=1;
}
else if (z==a[x][y]){
cnt[x][y]++;
cnt[y][x]++;
}
}
int ans2=m-dij();
p.clear();
for (i=1;i<=n;i++){
num[i].clear();
}
for (i=1;i<=n;i++){
for (j=1;j<=n;j++){
if (dist[i]==dist[j]+a[j][i]){
add(j,i,cnt[j][i]);
}
}
}
printf("%d %d\n",dinic(1,n),ans2);
}
}
然后一道规律题1020 I Wanna Become A 24-Point Master,在打表的过程中,当发现可以用x-x凑0的时候这个题目就变成了凑4和6的简单过程,前13项需要打表,到9还好,后面就费劲了,花了些时间。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int main() {
long long n,i,j;
while (scanf("%lld",&n)!=EOF) {
if (n==1||n==2||n==3)puts("-1");
else if (n==4){
printf("1 * 2\n");
printf("5 + 3\n");
printf("6 + 4\n");
}
else if (n==5){
printf("1 * 2\n");
printf("3 * 6\n");
printf("7 - 4\n");
printf("8 / 5\n");
}
else if (n==6){
printf("1 + 2\n");
printf("3 + 4\n");
printf("5 / 6\n");
printf("7 + 8\n");
printf("9 * 10\n");
}
else if (n==7){
printf("1 + 2\n");
printf("3 + 4\n");
printf("5 + 8\n");
printf("6 + 9\n");
printf("10 / 7\n");
printf("11 + 12\n");
}
else if (n==8){
printf("1 - 2\n");
printf("3 - 4\n");
printf("5 + 6\n");
printf("7 * 9\n");
printf("8 + 11\n");
printf("10 + 13\n");
printf("12 + 14\n");
}
else if (n==9){
printf("1 + 2\n");
printf("3 + 4\n");
printf("5 - 6\n");
printf("7 + 10\n");
printf("8 + 11\n");
printf("13 / 9\n");
printf("14 - 15\n");
printf("16 + 12\n");
}
else if (n==10){
printf("1 + 2\n");
printf("3 / 4\n");
printf("5 / 6\n");
printf("7 / 8\n");
printf("9 / 10\n");
printf("11 + 12\n");
printf("13 + 16\n");
printf("14 + 17\n");
printf("15 + 18\n");
}
else if (n==11){
printf("1 + 2\n");
printf("3 - 4\n");
printf("5 - 6\n");
printf("7 / 8\n");
printf("9 / 10\n");
printf("12 + 15\n");
printf("11 * 13\n");
printf("14 * 18\n");
printf("16 + 17\n");
printf("19 + 20\n");
}
else if (n==12){
printf("1 + 2\n");
printf("13 + 3\n");
printf("14 + 4\n");
printf("15 / 5\n");
printf("6 + 7\n");
printf("17 + 8\n");
printf("18 + 9\n");
printf("19 + 10\n");
printf("20 + 11\n");
printf("21 / 12\n");
printf("16 * 22\n");
}
else if (n==13){
printf("1 + 2\n");
printf("14 / 3\n");
printf("4 + 5\n");
printf("16 / 6\n");
printf("7 + 8\n");
printf("18 / 9\n");
printf("10 + 11\n");
printf("20 + 12\n");
printf("21 / 13\n");
printf("15 * 17\n");
printf("23 * 19\n");
printf("24 * 22\n");
}
else {
printf("1 + 2\n");
printf("%lld + 3\n",n+1);
printf("%lld + 4\n",n+2);
printf("%lld / 5\n",n+3);
printf("6 + 7\n");
printf("%lld + 8\n",n+5);
printf("%lld + 9\n",n+6);
printf("%lld + 10\n",n+7);
printf("%lld + 11\n",n+8);
printf("%lld / 12\n",n+9);
printf("%lld * %lld\n",n+4,n+10);
printf("14 - 13\n");
if (n>=15){
for (i=15;i<=n;i++){
printf("%lld * %lld\n",n+i-3,i);
}
}
printf("%lld + %lld\n",n+11,2*n-2);
}
}
}