标算未知= =但是由于数据比较水,显然是错的最大流&显然能被卡掉的迭代加深搜索&显然不可能过的A*&有理有据的模拟退火都能过(雾)
我写的是个搜索+每层一次spfa,每次在最短路上搜一条边删除,看起来没问题。但是如果是这种图:
/ 2...k \
1 - 3...k+1-n
\ 4...k+2/
是T的,然而。。。
附代码
#include<queue>
#include<cstring>
#include<iostream>
using namespace std;
#define N 55
#define M 4010
inline void read(int &a){
a=0;char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch<='9'&&ch>='0') a=a*10+ch-'0',ch=getchar();
}
queue<int> q;
int n,m,k;
bool inq[N];
int pre[N],dis[N],len;
int beg[N],to[M],nex[M];
bool sc[N];
inline void Add(int a,int b){nex[++len]=beg[a],beg[a]=len,to[len]=b;}
inline void spfa(){
memset(dis,0x3f3f,sizeof(dis));
memset(inq,0,sizeof(inq));
q.push(1);
dis[1]=0;
while(!q.empty()){
int st=q.front();q.pop();
for(int i=beg[st];i;i=nex[i]){
if(sc[to[i]]) continue;
if(dis[to[i]]>dis[st]+1){
dis[to[i]]=dis[st]+1;
pre[to[i]]=st;
if(!inq[to[i]]){
inq[to[i]]=1;
q.push(to[i]);
}
}
}
inq[st]=0;
}
}
int flag;
int path[N][N];
void dfs(int p){
if(flag) return;
spfa();
if(dis[n]>k){
flag=1;
return;
}
if(!p) return;
int tot=0;
for(int i=n;i!=1;i=pre[i]) path[p][tot++]=i;
for(int i=1;i<tot;i++){
if(sc[path[p][i]]) continue;
sc[path[p][i]]=1;
dfs(p-1);
sc[path[p][i]]=0;
}
}
int main(){
while(~scanf("%d%d%d",&n,&m,&k),n+m+k){
len=flag=0;
memset(beg,0,sizeof(beg));
memset(sc,0,sizeof(sc));
for(int i=0,a,b;i<m;i++){
read(a);read(b);
Add(a,b);
}
for(int i=0;i<n;i++){
dfs(i);
if(flag){
printf("%d\n",i);
break;
}
}
}
return 0;
}