codeforces图论训练

codeforces图论训练

President’s Path codeForces-416E

题目描述:给出n个点m条边的无向图,求出对于任意两点之间的所有最短路覆盖的边数。
题目解析:首先题目数据范围较小,有500左右的点,首先可以用floyd预处理出任意两点之间的最短路,然后用 dp[i][j]表示有多少条与i相邻的边位于从i到j的最短路径上,计算出指向j的边中在从i到j最短路上的个数,最后统计这条路径上总共有多少条边,枚举k就能得到结果。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
#define eps 1e-5
template<class T> void read(T&num) {
    char CH; bool F=false;
    for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
    for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
    F&&(num=-num);
}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
int lowbit(int x){return x&(-x);}
const int maxn=500+100;
const int inf=0x3f3f3f3f;
const ll mod=1e9+7;
int n,m;
int dis[maxn][maxn],mp[maxn][maxn],dp[maxn][maxn];
void floyd(){
    for(int k=1;k<=n;k++)
  for(int i=1;i<=n;i++)
         for(int j=1;j<=n;j++)
          dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
int main(){
 read(n);
 read(m);
    memset(mp,inf,sizeof mp);
    memset(dis,0,sizeof dis);
    memset(dp,0,sizeof dp);
    while(m--){
     int u,v,w;
     read(u);read(v);read(w);
        mp[u][v]=mp[v][u]=w;
    }
    memcpy(dis,mp,sizeof mp);
    for(int i=1;i<=n;i++) dis[i][i]=0;
    floyd();
    for(int i=1;i<=n;i++){
        for(int k=1;k<=n;k++){
         for(int j=1;j<=n;j++){
                if(mp[i][k]!=inf&&dis[i][j]==dis[k][j]+mp[i][k]){
                 dp[i][j]++;
    } 
            }
        }
    }
    for(int i=1;i<=n;i++){
     for(int j=i+1;j<=n;j++){
            int ans=0;
            for(int k=1;k<=n;k++){
                if(dis[i][j]==dis[i][k]+dis[k][j]) ans+=dp[k][j];
            }
            printf("%d%c",ans,"\n "[i!=n-1]);
        }
   }
}

Mouse Hunt codeForces-1027D

题目大意:有n个屋子和1只老鼠,老鼠会从第i间房子跑到ai 间房子。在每间房子放捕鼠夹都有代价wi,而老鼠的初始位置可能是任何一个房间,为了保证抓到老鼠你需要在若干房间放上捕鼠夹,求最小代价和。
题目解析:简单来说就是有n个点,n条边的图。我们需要对这个图中的环进行分析,只需要取这个环中的最小值,就是答案。所以这道题有多种解法,比如使用tarjan把每个强连通分量缩点,把留下的最小wi相加就是答案。或者使用dfs找环,同时判断环内最小的wi。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
#define eps 1e-5
template<class T> void read(T&num) {
    char CH; bool F=false;
    for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
    for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
    F&&(num=-num);
}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
int lowbit(int x){return x&(-x);}
const int maxn=3e5+100;
const int inf=0x3f3f3f3f;
const ll mod=1e9+7;
int n;
int w[maxn],vis[maxn],sum=0;
int a[maxn];
int dfs(int x,int fa){
 if(vis[x]) return inf;
 vis[x]=fa;
 int y=a[x],minn=inf;
 if(vis[y]==fa){
  minn=min(w[x],minn);
  int k=a[x];
  while(k!=x){
         minn=min(w[k],minn);
         k=a[k];
  }
  return minn;
   }
   return dfs(a[x],fa);
}
int main(){
    read(n);
 memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++) read(w[i]);
    for(int i=1;i<=n;i++) read(a[i]);
    for (int i=1;i<=n;i++){
        int k=dfs(i,i);
        if(k<inf) sum+=k;
    }
    printf("%d\n",sum);
    return 0;
}

你可能感兴趣的:(codeforces图论训练)