HDU 2433 Travel 枚举+最短路
2015-10-23 15:48
495 查看
题意:有1~N个点,有M条边,无向图,sum=(每个点到其它个点的最短路程的总和),问你当删除M条边的i-th边时,sum=?
想法:两个步骤:1.先求出最开始的sum;2.求出删的那条边e(u,v),u到v的最短距离,newsum=sum-2+2*dis[u->v]。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define inf 0x7fffffff
using namespace std;
const int nodes=100+5;
const int edges=3000+5;
int n,m;
int sum;
struct edge
{
int u,v;
}par[edges];
struct node
{
int u,v,next;
}e[edges*2];
int head[nodes],cnt;
void Init()
{
memset(head,-1,sizeof(head));
cnt=0;
}
void add(int a,int b)
{
e[cnt].u=a;
e[cnt].v=b;
e[cnt].next=head[a];
head[a]=cnt++;
}
int spfa(int s,int t,int liu,int liv)
{
int mark=1;
int dis[nodes],vis[nodes];
queue<int>q;
while(!q.empty()) q.pop();
for(int i=1;i<=n;i++)
{
dis[i]=inf;
vis[i]=0;
}
dis[s]=0;
vis[s]=1;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i+1;i=e[i].next)
{
int v=e[i].v;
if(e[i].u==liu&&e[i].v==liv&&mark)
{
mark=0;
continue;
}
if(dis[v]>dis[u]+1)
{
dis[v]=dis[u]+1;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
if(liu!=-1) return dis[t];
int tot=0;
for(int i=1;i<=n;i++)
{
if(i==s) continue;
tot+=dis[i];
}
return tot;
}
void Input()
{
for(int i=1;i<=m;i++)
{
scanf("%d%d",&par[i].u,&par[i].v);
add(par[i].u,par[i].v);
add(par[i].v,par[i].u);
}
}
void treatment()
{
sum=0;
for(int i=1;i<=n;i++)
{
sum+=spfa(i,n,-1,-1);
}
for(int i=1;i<=m;i++)
{
int res=spfa(par[i].u,par[i].v,par[i].u,par[i].v);
if(res==inf) printf("INF\n");
else printf("%d\n",sum-2+2*res);
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
Init();
Input();
treatment();
}
return 0;
}
想法:两个步骤:1.先求出最开始的sum;2.求出删的那条边e(u,v),u到v的最短距离,newsum=sum-2+2*dis[u->v]。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define inf 0x7fffffff
using namespace std;
const int nodes=100+5;
const int edges=3000+5;
int n,m;
int sum;
struct edge
{
int u,v;
}par[edges];
struct node
{
int u,v,next;
}e[edges*2];
int head[nodes],cnt;
void Init()
{
memset(head,-1,sizeof(head));
cnt=0;
}
void add(int a,int b)
{
e[cnt].u=a;
e[cnt].v=b;
e[cnt].next=head[a];
head[a]=cnt++;
}
int spfa(int s,int t,int liu,int liv)
{
int mark=1;
int dis[nodes],vis[nodes];
queue<int>q;
while(!q.empty()) q.pop();
for(int i=1;i<=n;i++)
{
dis[i]=inf;
vis[i]=0;
}
dis[s]=0;
vis[s]=1;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i+1;i=e[i].next)
{
int v=e[i].v;
if(e[i].u==liu&&e[i].v==liv&&mark)
{
mark=0;
continue;
}
if(dis[v]>dis[u]+1)
{
dis[v]=dis[u]+1;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
if(liu!=-1) return dis[t];
int tot=0;
for(int i=1;i<=n;i++)
{
if(i==s) continue;
tot+=dis[i];
}
return tot;
}
void Input()
{
for(int i=1;i<=m;i++)
{
scanf("%d%d",&par[i].u,&par[i].v);
add(par[i].u,par[i].v);
add(par[i].v,par[i].u);
}
}
void treatment()
{
sum=0;
for(int i=1;i<=n;i++)
{
sum+=spfa(i,n,-1,-1);
}
for(int i=1;i<=m;i++)
{
int res=spfa(par[i].u,par[i].v,par[i].u,par[i].v);
if(res==inf) printf("INF\n");
else printf("%d\n",sum-2+2*res);
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
Init();
Input();
treatment();
}
return 0;
}
相关文章推荐
- 自定义控件涉及到的attrs属性详解
- nginx favicon.ico 出现403 forbidden
- SharedPreferences详解
- 线程:安全终止与重启(二)
- 用户身份和用户管理
- Struts2中的Token令牌使用
- Maven 安装和配置
- 8.2.2 Optimizing DML Statements 优化DML 语句:
- 半天教会你玩git
- Xcode上传App到Appstore,报错Error ITMS-90049:"This bundle is invalid.The bundle...."
- LXC 配置网络
- C++的一些干货,有各种c++的资料
- 如何利用均衡器改善音质
- Hibernate批量插入数据
- 如何在程序中调用Caffe做图像分类
- mysql+keepalived主从切换脚本 转
- sitemesh
- 电信近期有充值送红包的活动
- 求s=a+aa+aaa+aaaa+aa...a的值,输出结果有误
- poj3187 Backward Digit Sums