最短路:SPAF
#include <bits/stdc++.h>
using namespace std;
#define maxn 1000000
#define ll long long
#define INF 0x3f3f3f3f
struct node{
int u,v,w;
int next;
}edge[maxn];
int head[maxn];
ll dis[maxn];
int cnt,n,t;
void init(){
memset(head,-1,sizeof head);
memset(dis,INF,sizeof dis);
cnt=0;
}
void add(int u, int v, int w, node edge[], int &cnt, int *head){
edge[cnt].u=u;
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void spfa(int st, ll *dis, int *head, node edge[]){
dis[st]=0;
queue<int> q;
q.push(st);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i = head[u]; ~i; i = edge[i].next ){
int v=edge[i].v;
if(dis[v] > dis[u] + (ll)edge[i].w){
dis[v] = dis[u] + (ll)edge[i].w;
q.push(v);
}
}
}
return ;
}
int main(){
while(~scanf("%d %d", &t, &n)){
init();
int u,v,w;
for(int i=0;i<t;i++){
scanf("%d %d %d", &u, &v, &w);
add(u, v, w, edge, cnt, head);
add(v, u, w, edge, cnt, head);
}
spfa(1, dis, head, edge);
cout<<dis[n]<<endl;
}
return 0;
}
最短路 :迪杰斯特拉(谜之优化,备用)
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cstdio>
#define INF 0x3f3f3f3f
#define maxn 1000000
using namespace std;
int n,t;
int d[maxn];
bool color[maxn];
vector< pair<int,int> >mp[maxn];
void init(){
memset(d,INF,sizeof(d));
memset(color,0,sizeof(color));
for(int i=0;i<=n;i++){
mp[i].clear();
}
}
void dijkstra(int st){
priority_queue< pair<int,int> > p;
d[st]=0;
p.push(make_pair(0,st));
while(!p.empty()){
pair<int,int> f = p.top();
p.pop();
int u=f.second;
color[u]=1;
if(d[u] < f.first*(-1)) continue;
for(int j=0; j<mp[u].size(); j++){
int v=mp[u][j].first;
if(color[v]==1) continue;
if(d[v]>d[u]+mp[u][j].second){
d[v]=d[u]+mp[u][j].second;
p.push(make_pair(d[v]*(-1),v));
}
}
}
}
int main(){
while(~scanf("%d %d", &t, &n)){
init();
int u,v,w;
for(int i=0;i<t;i++){
scanf("%d %d %d", &u, &v, &w);
mp[u].push_back(make_pair(v,w));
mp[v].push_back(make_pair(u,w));
}
dijkstra(1);
printf("%d\n", d[n]);
}
return 0;
}
多元最短路:Floyed-Warshall算法
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
int mp[1005][1005];
int main(){
int n,m,x;
scanf("%d %d %d", &n, &m, &x);
int u,v,k;
for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){
mp[i][j]=0x3f3f3f;
}
}
for(int i=0;i<=n;i++){
mp[i][i]=0;
}
for(int i=0;i<m;i++){
scanf("%d %d %d", &u, &v, &k);
mp[u][v]=k;
}
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][k]+mp[k][j],mp[i][j]);
}
}
}
int ans=0;
for(int i=1;i<=n;i++){
ans=max(mp[i][x]+mp[x][i],ans);
}
printf("%d\n", ans);
return 0;
}
无向图的最小生成树:Kruskal算法
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 100000
struct node{
int u,v,w;
}edge[maxn];
int fa[maxn];
int cnt;
int n,m;
void init(){
cnt=0;
}
void add(int u,int v,int w){
edge[u].u=u;
edge[u].v=v;
edge[u].w=w;
}
bool cmp(node a,node b){
return a.w<b.w;
}
int root(int x){
return fa[x]==x?x:fa[x]=root(fa[x]);
}
void unite(int x,int y){
x=root(x);
y=root(y);
if(x!=y) fa[y]=x;
}
bool ailke(int x,int y){
return root(x)==root(y);
}
int Kruskal(){
sort(edge,edge+m,cmp);
for(int i=0;i<=n;i++) fa[i]=i;
int ans=0,num=0;
for(int i=0;i<m;i++){
if(!ailke(edge[i].u,edge[i].v)){
unite(edge[i].u,edge[i].v);
ans+=edge[i].w;
num++;
}
if(num==n-1) return ans;
}
return 0;
}
int main(){
while(cin>>n&&n){
init();
cin>>m;
for(int i=0;i<m;i++){
cin>>edge[i].u>>edge[i].v>>edge[i].w;
}
cout<<Kruskal()<<endl;
}
}
无向图的最小生成树:Prim算法(备用)
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#define maxn 110
#define INF 0x3f3f3f3f
using namespace std;
int n,t;
int m[maxn][maxn];
void init(){
memset(m,INF,sizeof m);
}
int prim(){
int ans=0;
int min=INF;
int d[maxn],color[maxn],b[maxn];
for(int i=0;i<n;i++){
color[i]=0;
d[i]=m[0][i];
b[i]=0;
}
color[0]=1;
for(int i=1;i<n;i++){
min=INF;
int u=-1;
for(int j=0;j<n;j++){
if(!color[j]&&d[j]<min){
min=d[j];
u=j;
}
}
color[u]=1;
ans+=m[u][b[u]];
for(int j=1;j<n;j++){
if(!color[j]&&m[u][j]<d[j]){
d[j]=m[u][j];
b[j]=u;
}
}
}
return ans;
}
int main(){
while(cin>>n&&n){
cin>>t;
init();
int u,v,w;
for(int i=0;i<t;i++){
cin>>u>>v>>w;
u--;
v--;
m[u][v]=min(m[u][v],w);
m[v][u]=min(m[v][u],w);
}
cout<<prim()<<endl;
}
return 0;
}
有向图的最小生成树:最小树形图
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
#define maxn 10000
#define INF 0x3f3f3f3f
int X[maxn],Y[maxn];
double IN[maxn];
int PRE[maxn];
int ID[maxn];
int VIS[maxn];
int n,m,cnt;
struct node{
int u,v;
double w;
}edge[maxn];
double dtc(int a,int b){
return sqrt((double)((X[a]-X[b])*(X[a]-X[b])+(Y[a]-Y[b])*(Y[a]-Y[b])));
}
void add(int u,int v){
edge[cnt].u=u;
edge[cnt].v=v;
edge[cnt++].w=dtc(u,v);
}
double zhuliu(int root){
double ans=0;
while(1){
for(int i=1;i<=n;i++){
IN[i]=INF;
}
for(int i=0;i<cnt;i++){
if(edge[i].v==edge[i].u) continue;
else if(IN[edge[i].v]>edge[i].w){
PRE[edge[i].v]=edge[i].u;
IN[edge[i].v]=edge[i].w;
}
}
for(int i=1;i<=n;i++){
if(i!=root&&IN[i]==INF) return -1;
}
int num=0;
memset(ID,0,sizeof ID);
memset(VIS,0,sizeof VIS);
IN[root]=0;
for(int i=1;i<=n;i++){
ans+=IN[i];
int v=i;
while(!ID[v]&&v!=root&&VIS[v]!=i){
VIS[v]=i;
v=PRE[v];
}
if(v!=root&&!ID[v]){
ID[v]=++num;
for(int j=PRE[v];j!=v;j=PRE[j]){
ID[j]=num;
}
}
}
if(!num) break;
for(int i=1;i<=n;i++){
if(!ID[i]){
ID[i]=++num;
}
}
for(int i=0;i<m;i++){
int x=edge[i].u,y=edge[i].v;
edge[i].u=ID[x];
edge[i].v=ID[y];
if(ID[x]!=ID[y]){
edge[i].w-=IN[y];
}
}
n=num;
root=ID[root];
}
return ans;
}
int main(){
int u,v;
while(~scanf("%d %d", &n, &m)){
cnt=0;
for(int i=1;i<=n;i++){
scanf("%d%d", &X[i], &Y[i]);
}
for(int i=0;i<m;i++){
scanf("%d%d", &u, &v);
if(u!=v) add(u,v);
}
double ans=zhuliu(1);
if (ans == -1) printf("poor snoopy\n");
else printf("%.2f\n", ans);
}
return 0;
}
最大流:Dinic算法
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
#define maxn 1000000
#define INF 0x3f3f3f3f
int n,m,k;
int a,b,c;
int B,E;
int dis[maxn];
struct node{
int u,v,w;
int next;
}edge[maxn];
int head[maxn];
int cnt;
void init(){
memset(head,-1,sizeof head);
cnt=0;
}
void add(int u,int v){
edge[cnt].u=u;
edge[cnt].v=v;
edge[cnt].w=1;
edge[cnt].next=head[u];
head[u]=cnt++;
edge[cnt].u=v;
edge[cnt].v=u;
edge[cnt].w=0;
edge[cnt].next=head[v];
head[v]=cnt++;
}
bool bfs(){
memset(dis,-1,sizeof dis);
queue<int> q;
dis[B]=0;
q.push(B);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].v;
if(dis[v]==-1&&edge[i].w>0){
dis[v]=dis[u]+1;
q.push(v);
}
}
}
return dis[E]!=-1;
}
int dfs(int u,int w){
int ans=0;
if(u==E) return w;
for(int i=head[u];~i;i=edge[i].next){
if(edge[i].w>0&&dis[edge[i].v]==dis[u]+1){
int num=min(edge[i].w,w-ans);
num=dfs(edge[i].v,num);
ans+=num;
edge[i].w-=num;
edge[i^1].w+=num;
}
}
if(!ans) dis[u]=-2;
return ans;
}
int dinic(){
int ans=0;
int num;
while(bfs()){
while(num=dfs(B,INF)) ans+=num;
}
return ans;
}
int main(){
cin>>n>>m>>k;
init();
B=0;
E=n+n+m+k+1;
for(int i=1;i<=m;i++){
add(B,n+i);
}
for(int i=1;i<=k;i++){
add(n+m+i,E);
}
for(int i=1;i<=n;i++){
add(i,n+m+k+i);
cin>>a>>b;
while(a--){
cin>>c;
add(n+c,i);
}
while(b--){
cin>>c;
add(n+m+k+i,n+m+c);
}
}
printf("%d\n", dinic());
return 0;
}
最大流:EK算法(备用)
#include <bits/stdc++.h>
using namespace std;
#define maxn 1000
#define INF 0x3f3f3f
int cap[maxn][maxn];
int f[maxn][maxn];
int pre[maxn],p[maxn];
int k,m,n;
int EK(int s,int t){
int v,u;
int ans=0;
queue<int> q;
memset(f,0,sizeof(f));
while(1){
memset(p,0,sizeof(p));
p[s]=INF;
q.push(s);
while(!q.empty()){
u=q.front();
q.pop();
for(v=1 ;v<=n ;v++){
if(!p[v]&&cap[u][v]>f[u][v]){
pre[v]=u;
q.push(v);
p[v]=min(p[u],cap[u][v]-f[u][v]);
}
}
}
if(p[t]==0) break;
for(u=t;u!=s;u=pre[u]){
f[pre[u]][u] += p[t];
f[u][pre[u]] -= p[t];
}
ans+=p[t];
}
return ans;
}
int main(){
int a,b,c;
while(~scanf("%d %d", &k, &n)){
memset(cap,0,sizeof(cap));
for(int i=0;i<k;i++){
scanf("%d %d %d", &a, &b, &c);
cap[a][b]+=c;
}
printf("%d\n", EK(1,n));
}
return 0;
}
最小费用流最大流:MCMF_SPAF
#include <bits/stdc++.h>
using namespace std;
#define maxn 1000000
#define INF 0x3f3f3f3f
int n,m;
struct node{
int u,v,w,c;
int next;
}edge[maxn];
int head[maxn];
int per[maxn];
int dis[maxn];
int q[maxn];
int cnt;
int s,t,ans;
void init(){
memset(head,-1,sizeof head);
cnt=0;
}
void add(int u,int v,int w,int c){
edge[cnt].u=u;
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].c=c;
edge[cnt].next=head[u];
head[u]=cnt++;
edge[cnt].u=v;
edge[cnt].v=u;
edge[cnt].w=-w;
edge[cnt].c=0;
edge[cnt].next=head[v];
head[v]=cnt++;
}
bool spfa(){
memset(per,-1,sizeof per);
memset(dis,INF,sizeof dis);
dis[s]=0;
queue<int> q;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].v;
if(edge[i].c>0&&dis[u]+edge[i].w<dis[v]){
dis[v]=dis[u]+edge[i].w;
per[v]=i;
q.push(v);
}
}
}
return dis[t]!=INF;
}
void MCMF(){
int flow=0;
int ans=0;
while(spfa()){
int u=t;
int mini=INF;
while(u!=s){
if(edge[per[u]].c<mini){
mini=edge[per[u]].c;
}
u=edge[per[u]].u;
}
flow+=mini;
u=t;
while(u!=s){
edge[per[u]].c-=mini;
edge[per[u]^1].c+=mini;
u=edge[per[u]].u;
}
ans+=mini*dis[t];
}
printf("%d %d\n" ,flow ,ans);
}
int main(){
init();
cin>>n>>m>>s>>t;
int a,b,c,d;
for(int i=0;i<m;i++){
cin>>a>>b>>c>>d;
add(a,b,d,c);
}
MCMF();
return 0;
}
次小生成树:kruskal算法
#include<bits/stdc++.h>
using namespace std;
const int L=1e5+7;
const int inf=0x3f3f3f3f;
const int maxn=1000+7;
int father[maxn],n,m,num[maxn],nPos;
struct node{
int s,y,w;
}edge[L];
void init(){
for(int i=0;i<=n;i++)
father[i]=i;
}
int root(int x){
return father[x]==x?x:father[x]=root(father[x]);
}
void unite(int x,int y){
x=root(x);
y=root(y);
if(x!=y)
father[y]=x;
}
int alike(int x,int y){
return root(x)==root(y);
}
int secondTree(int pos)
{
init();
int sum=0,cnt=0;
for(int i=0;i<m;i++)
{
if(cnt==n-1)
break;
if(i==pos)
continue;
if(!alike(edge[i].s,edge[i].y)){
unite(edge[i].s,edge[i].y);
sum+=edge[i].w;
cnt++;
}
}
return cnt!=n-1?-1:sum;
}
int cmp(node a,node b){
return a.w<b.w;
}
int kruskal(){
init();
sort(edge,edge+m,cmp);
int sum=0,cnt=0;
for(int i=0;i<m;i++)
{
if(cnt==n-1)
break;
if(!alike(edge[i].s,edge[i].y)){
unite(edge[i].s,edge[i].y);
sum+=edge[i].w;
cnt++;
num[++nPos]=i;
}
}
return cnt!=n-1?-1:sum;
}
void read(){
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
scanf("%d%d%d",&edge[i].s,&edge[i].y,&edge[i].w);
}
void solve(){
int Min=inf;
nPos=0;
int mst=kruskal();
if(mst==-1) {
printf("-1\n");
return;
}
for(int i=1;i<=nPos;i++){
int secmst=secondTree(num[i]);
if(secmst!=-1)
Min=min(Min,secmst);
}
if(Min!=inf&&Min!=mst)
printf("%d\n",Min);
else
printf("-1\n");
}
int main(){
int t;
scanf("%d",&t);
while(t--){
read();
solve();
}
return 0;
}
LCA:暴力求解
#include <bits/stdc++.h>
using namespace std;
#define maxn 10010
vector<int> tree[maxn];
int fa[maxn];
int deep[maxn];
bool find_root[maxn];
int root,n,q;
void dfs(int x){
for(int i=0;i<tree[x].size();i++){
int y=tree[x][i];
deep[y]=deep[x]+1;
fa[y]=x;
dfs(y);
}
}
void init(){
for(int i=1;i<=n;i++){
if(!find_root[i]){
root=i;
break;
}
}
deep[root]=1;
fa[root]=root;
dfs(root);
}
int lca(int x,int y){
while(deep[x]>deep[y]) x=fa[x];
while(deep[x]<deep[y]) y=fa[y];
while(x!=y){
x=fa[x];
y=fa[y];
}
return x;
}
int main(){
scanf("%d %d", &n, &q);
memset(find_root,false,sizeof find_root);
int x,y;
for(int i=1;i<n;i++){
scanf("%d %d", &x, &y);
tree[x].push_back(y);
find_root[y]=true;
}
init();
while(q--){
scanf("%d %d", &u, &v);
printf("%d\n", lca(u,v));
}
return 0;
}
LCA:倍增优化
#include <bits/stdc++.h>
using namespace std;
#define maxn 10010
vector<int> tree[maxn];
int anc[maxn][25];
int fa[maxn];
int deep[maxn];
bool find_root[maxn];
int root,n,q;
void dfs(int x){
anc[x][0]=fa[x];
for(int i=1;i<=22;i++){
anc[x][i]=anc[anc[x][i-1]][i-1];
}
for(int i=0;i<tree[x].size();i++){
int y=tree[x][i];
fa[y]=x;
deep[y]=deep[x]+1;
dfs(y);
}
}
void init(){
for(int i=1;i<=n;i++){
if(!find_root[i]){
root=i;
break;
}
}
deep[root]=1;
fa[root]=root;
dfs(root);
}
int lca(int x,int y) {
if (deep[x]<deep[y]) swap(x,y);
for (int i=22;i>=0;i--) {
if (deep[y]<=deep[anc[x][i]]) {
x=anc[x][i];
}
}
if (x==y) return x;
for (int i=22;i>=0;i--){
if (anc[x][i]!=anc[y][i]) {
x=anc[x][i];
y=anc[y][i];
}
}
return anc[x][0];
}
int main(){
scanf("%d %d", &n, &q);
memset(find_root,false,sizeof find_root);
int u,v;
for(int i=1;i<n;i++){
scanf("%d %d", &u, &v);
tree[u].push_back(v);
find_root[v]=true;
}
init();
while(q--){
scanf("%d %d", &u, &v);
printf("%d\n", lca(u,v));
}
return 0;
}
LCA:欧拉序+ST表
#include <bits/stdc++.h>
using namespace std;
#define maxn 10010
vector<int> tree[maxn];
struct node{
int deep;
int m;
}a[maxn<<2],num[maxn<<2][25];
int first[maxn];
int deep[maxn];
bool find_root[maxn];
int root,n,q;
int cnt;
node calc(node a,node b){
if(a.deep<b.deep) return a;
return b;
}
void dfs(int x){
first[x]=cnt;
if(tree[x].size()==0){
a[cnt].m=x;
a[cnt++].deep=deep[x];
}
for(int i=0;i<tree[x].size();i++){
int y=tree[x][i];
deep[y]=deep[x]+1;
a[cnt].m=x;
a[cnt++].deep=deep[x];
dfs(y);
}
}
void ST(){
int l=int(log((double)cnt)/log(2.0));
for(int j=1;j<=l;j++){
for(int i=1;i+(1<<(j-1))-1<=cnt;i++){
num[i][j]=calc(num[i][j-1], num[i+(1<<(j-1))][j-1]);
}
}
}
void init(){
for(int i=1;i<=n;i++){
if(!find_root[i]){
root=i;
break;
}
}
cnt=1;
deep[root]=1;
dfs(root);
cnt--;
for(int i=1;i<=cnt;i++){
num[i][0]=a[i];
}
ST();
}
int rmq(int l,int r){
l=first[l];
r=first[r];
if(l>r) swap(l,r);
int k=int(log((double)(r-l+1))/log(2.0));
return calc(num[l][k],num[r-(1<<k)+1][k]).m;
}
int main(){
int x,y;
scanf("%d %d", &n, &q);
memset(find_root,false,sizeof find_root);
for(int i=1;i<n;i++){
scanf("%d %d", &x, &y);
tree[x].push_back(y);
find_root[y]=true;
}
init();
while(q--){
scanf("%d %d", &x, &y);
printf("%d\n", rmq(x,y));
}
return 0;
}
Targan算法:割点
#include <bits/stdc++.h>
using namespace std;
#define maxn 1000100
struct node{
int u,v;
int next;
}edge[maxn];
int dfn[maxn],low[maxn];
int head[maxn];
int cnt,total;
void init(){
memset(head,-1,sizeof head);
cnt=total=0;
}
void add(int u,int v){
edge[cnt].u=u;
edge[cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void tarjan(int u,int fa){
dfn[u]=low[u]=++total;
int k=0;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].v;
if(!dfn[v]){
k++;
tarjan(v,u);
low[u]=min(low[u],low[v]);
if((u!=fa&&dfn[u]<=low[v])||(u==fa&&k>1)){
cout<<u<<endl;
}
}else if(fa!=v){
low[u]=min(low[u],dfn[v]);
}
}
}
int n,m;
int main(){
int u,v;
scanf("%d %d", &n, &m);
init();
for(int i=0;i<m;i++){
scanf("%d %d", &u, &v);
add(u,v);
add(v,u);
}
for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,i);
for(int i=1;i<=n;i++) cout<<i<<" "<<dfn[i]<<" "<<low[i]<<endl;
return 0;
}
Tarjan算法:割边
#include <bits/stdc++.h>
using namespace std;
#define maxn 100010
struct node{
int u,v;
int next;
}edge[maxn];
int dfn[maxn],low[maxn];
int head[maxn];
int cnt,total;
void init(){
memset(head,-1,sizeof head);
cnt=0;
total=0;
}
void add(int u,int v){
edge[cnt].u=u;
edge[cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void tarjan(int u,int fa){
dfn[u]=low[u]=++total;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].v;
if(!dfn[v]){
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]){
cout<<u<<" "<<v<<endl;
}
}else if(fa!=v){
low[u]=min(low[u],dfn[v]);
}
}
}
int n,m;
int main(){
int u,v;
scanf("%d %d", &n, &m);
init();
for(int i=0;i<m;i++){
scanf("%d %d", &u, &v);
add(u,v);
add(v,u);
}
for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,i);
return 0;
}
Tarjan算法:强连通分量
#include <bits/stdc++.h>
using namespace std;
#define maxn 100010
struct node{
int u,v;
int next;
}edge[maxn];
int dfn[maxn],low[maxn];
int head[maxn];
int cnt,total;
stack<int> st;
void init(){
while(!st.empty()) st.pop();
memset(head,-1,sizeof head);
cnt=0;
total=0;
}
void add(int u,int v){
edge[cnt].u=u;
edge[cnt].v=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void tarjan(int u){
dfn[u]=low[u]=++total;
st.push(u);
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].v;
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}else {
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]){
while(1){
int t=st.top();
st.pop();
cout<<t<<" ";
if(t==u) break;
}
cout<<endl;
}
return ;
}
int n,m;
int main(){
int u,v;
scanf("%d %d", &n, &m);
init();
for(int i=0;i<m;i++){
scanf("%d %d", &u, &v);
add(u,v);
}
for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
return 0;
}
BFS
#include <cstdio>
#include <cstring>
using namespace std;
int bx,by,ex,ey,bs,n,m;
char bf[10];
int mp[100][100][4];
int ans;
void bl(int x,int y,int z){
if(z==0){
if(x-1>=0&&mp[x-1][y][z]==0) mp[x-1][y][z]=ans+1;
if(x-2>=0&&mp[x-2][y][z]==0&&mp[x-1][y][z]!=-1) mp[x-2][y][z]=ans+1;
if(x-3>=0&&mp[x-3][y][z]==0&&mp[x-1][y][z]!=-1) mp[x-3][y][z]=ans+1;
}
if(z==2){
if(x+1<=n&&mp[x+1][y][z]==0) mp[x+1][y][z]=ans+1;
if(x+2<=n&&mp[x+2][y][z]==0&&mp[x+1][y][z]!=-1) mp[x+2][y][z]=ans+1;
if(x+3<=n&&mp[x+3][y][z]==0&&mp[x+1][y][z]!=-1) mp[x+3][y][z]=ans+1;
}
if(z==1){
if(y-1>=0&&mp[x][y-1][z]==0) mp[x][y-1][z]=ans+1;
if(y-2>=0&&mp[x][y-2][z]==0&&mp[x][y-1][z]!=-1) mp[x][y-2][z]=ans+1;
if(y-3>=0&&mp[x][y-3][z]==0&&mp[x][y-1][z]!=-1) mp[x][y-3][z]=ans+1;
}
if(z==3){
if(y+1<=m&&mp[x][y+1][z]==0) mp[x][y+1][z]=ans+1;
if(y+2<=m&&mp[x][y+2][z]==0&&mp[x][y+1][z]!=-1) mp[x][y+2][z]=ans+1;
if(y+3<=m&&mp[x][y+3][z]==0&&mp[x][y+1][z]!=-1) mp[x][y+3][z]=ans+1;
}
if(mp[x][y][(z+1+4)%4]==0) mp[x][y][(z+1+4)%4]=ans+1;
if(mp[x][y][(z-1+4)%4]==0) mp[x][y][(z-1+4)%4]=ans+1;
}
int bfs(){
for(int i=0;i<4;i++){
if(mp[ex][ey][i]!=0){
return mp[ex][ey][i];
}
}
int a=0;
ans++;
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
for(int k=0;k<4;k++){
if(ans==mp[i][j][k]){
bl(i,j,k);
a=1;
}
}
}
}
if(a==0)
return 0;
bfs();
}
int main() {
int a;
while(~scanf("%d %d", &n, &m)&&(n||m)){
memset(mp,0,sizeof(mp));
ans=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%d", &a);
if(a==0) for(int k=0;k<4;k++){
if(mp[i][j][k]==0) mp[i][j][k]=0;
if(mp[i+1][j][k]==0) mp[i+1][j][k]=0;
if(mp[i+1][j+1][k]==0) mp[i+1][j+1][k]=0;
if(mp[i][j+1][k]==0) mp[i][j+1][k]=0;
}
else for(int k=0;k<4;k++) mp[i][j][k]=-1,mp[i+1][j][k]=-1,mp[i+1][j+1][k]=-1,mp[i][j+1][k]=-1;
}
}
scanf("%d %d %d %d %s", &bx, &by, &ex, &ey, bf);
for(int i=0;i<=m;i++){
for(int k=0;k<4;k++){
mp[0][i][k]=-1;
mp[n][i][k]=-1;
}
}
for(int i=0;i<=n;i++){
for(int k=0;k<4;k++){
mp[i][0][k]=-1;
mp[i][m][k]=-1;
}
}
if(bf[0]=='n') bs=0;
if(bf[0]=='s') bs=2;
if(bf[0]=='w') bs=1;
if(bf[0]=='e') bs=3;
mp[bx][by][bs]=1;
if(mp[ex][ey][0]==-1||mp[bx][by][0]==-1)
printf("-1\n");
else
printf("%d\n", bfs()-1);
}
return 0;
}
DFS
#include <bits/stdc++.h>
using namespace std;
char mp[105][105];
int n,m;
int dfs(int x,int y){
if(mp[x][y]=='@'&&x<n&&x>=0&&y<m&&y>=0){
mp[x][y]='*';
dfs(x+1,y),dfs(x-1,y),dfs(x,y+1),dfs(x,y-1);
dfs(x+1,y+1),dfs(x-1,y-1),dfs(x-1,y+1),dfs(x+1,y-1);
return 1;
}
return 0;
}
int main() {
while(~scanf("%d %d", &n, &m)&&(m||n)){
memset(mp,0,sizeof(mp));
for(int i=0;i<n;i++){
scanf("%s", mp[i]);
}
int ans=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
ans+=dfs(i,j);
}
}
printf("%d\n", ans);
}
return 0;
}